Spring 将 Bean 注册到的 IoC 容器方式主要有XML配置文件方式、JavaConfig方式、注解方式这三种。
XML方式注册Bean
在XML里配置Bean;或配置扫描需要注册为 Spring容器的Bean的包路径,Spring会扫描该包下的所有实体并将其注册为容器中的Bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="springContextUtil" class="com.commons.SpringContextUtil" ></bean> <bean id="userService" class="com.xxx.service.imp.UserServiceImpl" > <property name="springContextUtil" ref="springContextUtil"/> </bean> <context:component-scan base-package="com.xxx.service" />
|
JavaConfig方式注册Bean
使用@Configuration
注解来定义一个JavaConfig
配置类,在配置类里使用@Bean
注解来定义一个Bean。
标注了@Bean
的方法,其返回值将作为一个Bean
定义注册到Spring
的IoC
容器,方法名将默认成为该Bean定义的id
。
如果一个Bean依赖其它 Bean,则直接调用依赖 Bean 的创建方法即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Configuration public class BeanConfig { @Bean public UserService userService() { return new UserServiceImpl(); } @Bean public LoginService loginService() { return new LoginServiceImpl(xxxxService()); } @Bean public XxxxService xxxxService() { return new XxxxServiceImpl(); } }
|
注解方式注册Bean
前面讲了@Configuration
和@Bean
注解,还有一些在Spring Boot
中常用的 Annotation注解。
@ComponentScan
该注解对应XML配置形式中的**context:component-scan元素,用于将标注了元注解(如:@Component,@Service,@Repository,@Controller**)的 Bean 定义类批量采集到 Spring IoC 容器中。
此注解可以通过basePackages
属性来细粒度地定制自动扫描的范围;如果不设置,则默认会从@ComponentScan
的类所在的包进行扫描。
在Spring Boot项目中,可用省略此注解,因为入口类的@SpringBootApplication
注解包含了@ComponentScan
,会自动扫描入口类所在的包及下级包里的类并注册为Bean
,基于这个原因需要特别注意的是入口类必须放在包路径,不能直接放在main/java
文件夹下,否则会因没有默认的包路径而无法启动的错误:
** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
@Import
在XML配置中,使用<import resource="xxxx.xml"/>
的形式将多个配置文件整合到一个配置中;在JavaConfig
中可以使用@Import
达到同样的目的。
1 2 3 4 5
| @Configuration @Import(BeanConfig.class) public class MyConfig(){ ... }
|
@ImportResource
使用该注解将XML配置文件合并到当前JavaConfig
配置的容器中。
1 2 3 4 5 6
| @Configuration @Import(BeanConfig.class) @ImportResource(locations = {"classpath:dubbo-config.xml","classpath:another-context.xml"}) public class MyConfig(){ ... }
|
识别一个接口多个实现类
Spring 容器默认是根据接口类型来查找其实现类的 Bean
, 如果一个接口有多个实现类而不进行区分的话, 则注入拿到的可能不是想要的 Bean
, 这时应该给不同的实现类定义 Bean id来区分。
- 给接口的实现类定义 Bean id。
1 2 3 4 5 6 7 8
| @Service("ipFilter") public class IpFilter implements Filter { @Override public String doFilter(String str) { ...... } }
|
- 在需要注入的调用方使用
@Qualifier("ipFilter")
注解,指定需要的Bean。
1 2 3
| @Autowired @Qualifier("ipFilter") private Filter ipFilter;
|