Spring 提供了三种装配 Bean 的方式:
- 自动发现和自动装配(推荐使用)
- 通过 Java 显示配置
- 再 XML 文件中显示配置
自动发现和自动装配
Spring 从两个方面实现自动化装配 Bean:
- 组件扫描(component scanning): Spring 通过注解自动发现应用中所创建的 Bean
- 自动装配(autowiring): Spring 自动将 Bean 所依赖的其他 Bean 注入(@Autowried)
自动装配例子:
CD 接口
public interface CompactDisc {
void paly();
}
import org.springframework.stereotype.Component;
@Component // 使该对象会被 Spring 自动发现
public class Jay implements CompactDisc {
@Override
public void paly() {
System.out.println("正在播放周杰伦的JAY");
}
}
Spring 配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 表示该类为配置类
@ComponentScan // 自动扫描配置类所在包
public class CDPlayerConfig {
}
自动注入测试
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) // 自动创建 Spring 上下文
@ContextConfiguration(classes = CDPlayerConfig.class) // 指定 Spring 配置类
public class CDPlayerTest {
@Autowired // Spring 会自动注入跟它匹配的实例
private CompactDisc cd;
@Test
public void playTest() {
if (cd != null) {
cd.paly();
} else {
System.out.println("注入失败");
}
}
}
解释上面出现的注解
-
@Component:
使该类会被 Spring 的自动扫描发现,并为其创建 Bean,其 ID 为该类的首字母小写,也可以通过@Component("id_name")
指定ID名字,还有基于@Component
的三个扩展的注解:1.@controller
控制器(注入服务)2.@service
服务(注入dao)3.@repository
dao(实现dao访问) -
@ComponentScan:
默认会自动扫描包路径下面的(包括子包)所有有@Controller
、@Service
、@Repository
、@Component
注解的类,可以通过 basePackages 指定需要扫描的包如:@ComponentScan(basePackages="包名")
,多个@ComponentScan(basePackages= {"包1", "包2"})
。注意该注解需要在配置类上使用,也可以通过 XML 配置开启自动扫描:<context:component-scan base-package="com.project.dao" />
-
@Configuration:
声明该类为配置类 -
@Autowired:
Spring 会自动注入跟它匹配的实例,注意如果找不到与之匹配的实例会抛出异常,有多个与它匹配的实例也会抛出异常。@Autowired:
注解可以用在属性、方法及构造方法上。(让我疑惑的是 私有属性无 set 方法也可以注入成功)
Java显示的装配 Bean
将上面的 @Component
注解,跟 @ComponentScan
注解删除,现在Spring不会自动的发现跟装配Bean了。
接下来我们在配置类中通过Java代码手动的装配Bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 表示该类为配置类
public class CDPlayerConfig {
@Bean // 将该方法返回的对象注册为 Bean
public Jay jay() {
return new Jay();
}
}
注意:配置类中不应该包含任何业务逻辑,它也不因该侵入到任何业务逻辑代码中。
-
@Bean:
Spring 会将使用该注解方法返回的对象,注册为 Bena,方法体内可以写复杂的初始化逻辑,这适合用来产生初始化复杂的Bean对象。
通过 XML 显示的装配Bean
构造器装配
无参数的简单构造
<bean id="jay" class="jay类的全路径" />
注入对象
<bean id="id_name" class="类的全路径">
<constructor-arg ref="bena的id" />
</bean>
ref
: 接收通过id指定的Spring中的Bean作为参数
注入字面量
<bean id="id_name" class="类的全路径">
<constructor-arg value="字面量" />
</bean>
value
: 接收字面量作为参数
注入集合
<bean id="id_name" class="类的全路径">
<constructor-arg>
<list>
<vlaue>字面量</value>
<vlaue>字面量</value>
<vlaue>字面量</value>
</liet>
</constructor-arg>
</bean>
<bean id="id_name" class="类的全路径">
<constructor-arg>
<list>
<ref bean="bean_id-1" />
<ref bean="bean_id-2" />
<ref bean="bean_id-3" />
</liet>
</constructor-arg>
</bean>
也可以将<list>
标签改成<set>
,只是如果是 set 的话重复的值会被忽略掉。这两个标签都可以用来装配 List、Set、数组。
注入属性
<bean id="id_name" class="类的全路径">
<property name="att_name" ref="bean-id" />
</bean>
就像 <constructor-arg>
表示通过构造器注入一样,<property>
通过 setter 方法注入,ref
表示注入的是对象,如果是简单类型使用 value
,注入集合的方法更构造器一样。
网友评论