集中讲解bean织入
spring中主要用三种织入方式:
- 配置xml文件
- 同配置xml相对应的一种java类的配置写法
- 配置xml中自动扫描,注解织入
这三种配置看起来有些重复,使要做更多的选择。但是好处是,你有更多的选择,并且我们可以混合起来使用,只要自己的项目更适合。
权威的建议是,尽可能优先的选用扫描注解注入,然后配合java类方式的配置注入,因为相比于xml配置,java类要更安全。xml的缺点是所有的配置在xml文件中,使在代码中不能直观的看到配置,另外就是相对不安全。优点是namespace使用起来比javaclass方便。
1、自动注入
- 首先必须明确的配置扫描路径。两种方式:
- java类配置
在java配置类上加注解
@Configuration —》这是一个配置类
@ComponentScan —》扫描路径,如果不加参数,默认的是同一个包下。
加参数:
@ComponentScan(“package1”) 可以指定一个包
@ComponentScan(basePackages=”package1”) 可以指定参数名
@ComponentScan(basePackages={“package1”, “package2”}) 也可以指定多个包
@ComponentScan(basePackageClasses={XX.class, YY.class})还可以指定类
要特别注意的是,这样写,这些类所在的包会被指定被扫描路径,不是只扫描这几个类
- xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="xxxxx" />
</beans>
- @Component 注解在类上,说明该类被注解为spring的一个组件,spring要为该类创建一个bean,并管理它。可以在需要用到该bean的地方注入了。就是说我是一个bean。我可以注入给别人。
@Component 如果不带参数,那么默认使用类名首字母小写的方法作为beanId。可以加参数@Component(“myName”)指定beanId。
也可以使用JSR-330中@Named(“myName”)替代。极少用。
(插播)在junit中使用spring
引入spring的test包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
在测试类上使用注解:
@RunWith(SpringJUnit4ClassRunner.class)
(@RunWith是junit4的注解)
@ContextConfiguration(classes=xxxxConfig.class)
这里使用java类配置
在需要注入的属性上使用注解:
@Autowired
@Autowired
@Autowired可以用在构造器,setter方法,类属性上。
用来告诉spring,为该实例提供相应的bean注入。
实际上, @Autowired可以注解类的任何方法,spring都会努力去满足该方法参数对于bean的依赖要求。
如果有且仅有一个bean满足要求,那么就很愉快的注入了。
如果没有bean满足要求,那么会抛异常。
为避免异常,可使用@Autowired(required=false)。这样spring不会报错,但是留下了null值隐患,自己记得check null。
如果有多个满足的bean,那么也会抛异常,spring不知道应该注入哪一个。
@Autowired是spring特有的注解。在java中有个@Inject注解功能差不多。看到要知道。
@Bean
等同于xml的<bean>
。注解于方法上。
默认也是单例的。
spring监视被注解的方法。
xml配置
xml是spring中历史最悠久的配置方式。
最简的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context">
<!-- configuration details go here -->
</beans>
配置bean使用<bean>
标签
如果配置bean时不指定beanId,那么会使用class属性的值#数字作为id。如:<bean class="yunsheng.Student" />
,那么他的beanId就是yunsheng.Student#0。如果再次声明了同样的bean,那么id就是yunsheng.Student#1。
所以还是自己指定更好。
还有一点,class属性的值是字符串,也就是说,写错了也要到部署时才会发现,这点也不如javaConfig好。当然ide插件可以检查出,但是又会拉低ide的速度。
构造器注入和c-namespace写法注入
<bean id="cdPlayer" class="soundsystem.CDPlayer">
<constructor-arg ref="compactDisc" />
</bean>
VS
<bean id="cdPlayer" class="soundsystem.CDPlayer"
c:cd-ref="compactDisc" />
注意,c-namespace写法是spring3以上才有用。要引入一下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
... </beans>
构造器写法不多解析,注入ref,value,数据结构等。
c-namespace用的比较少,看一下:
属性注入:
<bean id="cdPlayer"
class="soundsystem.CDPlayer">
<property name="compactDisc" ref="compactDisc" />
</bean>
vs
p-namespace
<bean id="cdPlayer"
class="soundsystem.CDPlayer"
p:compactDisc-ref="compactDisc" />
组装配置文件。
当工程有多个项目,或者配置已经很复杂的情况下需要拆分配置文件,然后组装起来。
javaconfig配置
使用@Import引入javaConfig配置
使用@ImportResource引入xml配置
xml配置
使用<import>
标签玉如xml配置文件
但是xml中并没有一个标签是用来引入javaConfig的。引入的办法是使用<bean>
标签。直接当做一个bean,将javaConfig类引入。