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;