2、Spring注解与生命周期
自动装配无非就是默认加载bean、在一些情况下需要根据条件来选择合适的bean进行装配。
本文分为三部分, bean 加载方法、bean 生命周期、根据条件进行加载 bean
1、 注册Bean(组件)的方法
1.1、类上注解
通过@Controller、@Service、@Repository、@Component等 结合@ComponentScan
1.2、Bean注解
结合@ComponentScan 跟 @Configuration 使用,常用于导入第三方包
1.3、Import注解
-
快速导入一个组件到容器
值得注意的是,导入后的 bean name为带包名的全类名。
@Import({YourClass1.class,YourClass2.class}) -
导入一个选择器
首先实现 ImportSelecto r接口,然后在实现方法中反回 beanNames
@Import({YourSelector.class} -
导入一个 ImportbeanDefinitionsRegister 的实现类,导入 beanDefinitions 信息
@Import({YourBeanDefinitionsRegister})
其中,这三种类可以同时存在一个 Import 注解中,如下
@Import({YourClass.class,YourSelector.class,YourBeanDefinitionsRegister.class})
1.4、FactoryBean
注意:FactoryBean 是通过实现接口,完成 getObject 方法来获取 bean,而 BeanFactory 是spring 容器的实现的一个接口
@bean
public YourFactoryBean yourFactoryBean(){
return new YourFactoryBean();
}
//返回的是getObject的返回值
//如果非要得到FactoryBean,就通过增加&前缀的方法:context.getBean("&yourFactoryBean")
2、bean 生命周期
2.1 生命周期过程
- 初始化 spring 容器
- 加载 beanDefinition
- 执行 beanFactoryPostPorcess
- 初始化
- 构造方法创建对象
- 属性赋值 populateBean(beabName,exposedObject,mbd)
- 初始化bean:initializeBean
- invokeAwareMethods() 为相对应的Aware接口调用set方法赋值
- applyBeanPostProcessorsBeforeInitalization() 应用后置处理器的初始化前处理方法
- invokeInitMethods() 执行自定义的初始化方法 下文2.2
- applyBeanPostProcessorsAfterInitalization() 应用后置处理器的初始化后处理方法
- 销毁
- 单实例:容器关闭的时候
- 多实例:容器不会管理该bean,由jvm销毁
2.2 指定生命周期中执行方法
2.2.1 指定初始化和销毁方法
自动装配无非就是默认加载bean、在一些情况下需要根据条件来选择合适的bean进行装配。
本文分为三部分, bean 加载方法、bean 生命周期、根据条件进行加载 bean
1、 注册Bean(组件)的方法
1.1、类上注解
通过@Controller、@Service、@Repository、@Component等 结合@ComponentScan
1.2、Bean注解
结合@ComponentScan 跟 @Configuration 使用,常用于导入第三方包
1.3、Import注解
-
快速导入一个组件到容器
值得注意的是,导入后的 bean name为带包名的全类名。
@Import({YourClass1.class,YourClass2.class}) -
导入一个选择器
首先实现 ImportSelecto r接口,然后在实现方法中反回 beanNames
@Import({YourSelector.class} -
导入一个 ImportbeanDefinitionsRegister 的实现类,导入 beanDefinitions 信息
@Import({YourBeanDefinitionsRegister})
其中,这三种类可以同时存在一个 Import 注解中,如下
@Import({YourClass.class,YourSelector.class,YourBeanDefinitionsRegister.class})
1.4、FactoryBean
注意:FactoryBean 是通过实现接口,完成 getObject 方法来获取 bean,而 BeanFactory 是spring 容器的实现的一个接口
@bean
public YourFactoryBean yourFactoryBean(){
return new YourFactoryBean();
}
//返回的是getObject的返回值
//如果非要得到FactoryBean,就通过增加&前缀的方法:context.getBean("&yourFactoryBean")
2、bean 生命周期
2.1 生命周期过程
- 初始化 spring 容器
- 加载 beanDefinition
- 执行 beanFactoryPostPorcess
- 初始化
- 构造方法创建对象
- 属性赋值 populateBean(beabName,exposedObject,mbd) 下文2.2 属性赋值
- 初始化bean:initializeBean
- invokeAwareMethods() 为相对应的Aware接口调用set方法赋值
- applyBeanPostProcessorsBeforeInitalization() 应用后置处理器的初始化前处理方法
- invokeInitMethods() 执行自定义的初始化方法 下文2.3 指定生命周期中执行方法
- applyBeanPostProcessorsAfterInitalization() 应用后置处理器的初始化后处理方法
- 销毁
- 单实例:容器关闭的时候
- 多实例:容器不会管理该bean,由jvm销毁
2.2 属性赋值
2.2.1 使用@Value()
-
基本数据值
- @Value("abc")
-
SpEL
- @Value("#{6+3}")
-
${} 从配置文件中的值(环境变量中的值 enviroment )
- @Value("${your.name}")
@PropertySource("classpath:test.properties") 加载外部配置文件 并保存到运行环境中
2.2.2 使用xml
略
2.3 指定生命周期中执行方法
2.3.1 指定初始化和销毁方法
- 通过@Bean(init-method=”“,destory-method=”“)
- 通过类实现接口:InitializingBean ( 初始化方法 )、DisPoseableBean( 销毁方法 )
- 在 xml 配置中 initMethod 、destoryMethod
2.3.2 使用JSR250
在类方法上添加相应的方法来实现,注意:方法不能有参数和返回值
- @postConstruct : 在实例化对象并且属性赋值完成:执行初始化方法
- @PreDesotry : 在容器销毁bean之前执行
2.4 自动装配
2.4.1 spring注解
1、@Autowired 默认优先按照类型去容器中找对应的 bean,
如果存在相同类型的 bean 有多个,则按照名字取找 bean。
即使 bean 不存在也要赋值:@Autowired(required=false)
2、只根据名字装配:使用 @Qualifier("beanName")
3、@primary 首选 略。
2.4.2 Java规范注解
Spring 支持使用 @Resource(JSR250)和 @Inject(JSR330)
1、@Resource
- 默认按照属性名称装配,没有 @Primary、required=false 功能
2、 @Inject
- 需要导入依赖…… 功能和 autowired 一样
2.5 在bean中获取spring组件
通过实现Aware接口的相关子接口,即可在实现方法中获取spring容器自身的bean。
接口如下
ApplicationEventPublisherAware (org.springframework.context)
ServletContextAware (org.springframework.web.context)
MessageSourceAware (org.springframework.context)
ResourceLoaderAware (org.springframework.context)
SchedulerContextAware (org.springframework.scheduling.quartz)
NotificationPublisherAware (org.springframework.jmx.export.notification)
BeanFactoryAware (org.springframework.beans.factory)
EnvironmentAware (org.springframework.context)
EmbeddedValueResolverAware (org.springframework.context)
ImportAware (org.springframework.context.annotation)
BootstrapContextAware (org.springframework.jca.context)
ServletConfigAware (org.springframework.web.context)
LoadTimeWeaverAware (org.springframework.context.weaving)
BeanClassLoaderAware (org.springframework.beans.factory)
BeanNameAware (org.springframework.beans.factory)
ApplicationContextAware (org.springframework.context)
使用方法如下
@Component
public class UserService implements ApplicationContextAware {
public ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
3、动态加载bean
3.1 Profile
Spring提供可以根据当前环境,动态的激活和切换一系列bean的功能
默认是default环境
修改profile 环境的方法
-
使用命令行参数
-Dspring.profiles.active=dev // 默认是default
-
通过spring的无参构造方法,手动设置profile
代码如下
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.getEnvironment().setActiveProfiles("test"); context.register(BeanProfileConfig.class); context.refresh();
修改后,使用@Profile的方法,代码如下(@profile也可以写在类上,则表示控制类里面所有的@bean)
@Bean
@Profile("dev")
public DataSource dataSourceDev(@Value("${db.password}") String pwd) throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
return dataSource;
}
3.2 Conditional 注解按条件注入
@Conditional :表示按照一定的条件去注册bean springBoot 中解决自动装配
@Conditional({YourCondition.class})
新建类->实现Condition接口->完成实现方法。将这个类作为参数传入@Condition
@Condtional参数既可以作用在方法上1 (与@Bean共同出现) 也可以作用在类上2(与@Configuration同时出现)
作用分别为
1、判断是否创建某个bean
2、判断是否创建这个configuration下面的所有bean
- 通过@Bean(init-method=”“,destory-method=”“)
- 通过类实现接口:InitializingBean ( 初始化方法 )、DisPoseableBean( 销毁方法 )
- 在 xml 配置中 initMethod 、destoryMethod
2.2.2 使用JSR250
在类方法上添加相应的方法来实现,注意:方法不能有参数和返回值
- @postConstruct : 在实例化对象并且属性赋值完成:执行初始化方法
- @PreDesotry : 在容器销毁bean之前执行
2.4 自动装配
2.4.1 spring注解
1、@Autowired 默认优先按照类型去容器中找对应的 bean,
如果存在相同类型的 bean 有多个,则按照名字取找 bean。
即使 bean 不存在也要赋值:@Autowired(required=false)
2、只根据名字装配:使用 @Qualifier("beanName")
3、@primary 首选 略。
2.4.2 Java规范注解
Spring 支持使用 @Resource(JSR250)和 @Inject(JSR330)
1、@Resource
- 默认按照属性名称装配,没有 @Primary、required=false 功能
2、 @Inject
- 需要导入依赖…… 功能和 autowired 一样
2.5 在bean中获取spring组件
通过实现Aware接口的相关子接口,即可在实现方法中获取spring容器自身的bean。
接口如下
ApplicationEventPublisherAware (org.springframework.context)
ServletContextAware (org.springframework.web.context)
MessageSourceAware (org.springframework.context)
ResourceLoaderAware (org.springframework.context)
SchedulerContextAware (org.springframework.scheduling.quartz)
NotificationPublisherAware (org.springframework.jmx.export.notification)
BeanFactoryAware (org.springframework.beans.factory)
EnvironmentAware (org.springframework.context)
EmbeddedValueResolverAware (org.springframework.context)
ImportAware (org.springframework.context.annotation)
BootstrapContextAware (org.springframework.jca.context)
ServletConfigAware (org.springframework.web.context)
LoadTimeWeaverAware (org.springframework.context.weaving)
BeanClassLoaderAware (org.springframework.beans.factory)
BeanNameAware (org.springframework.beans.factory)
ApplicationContextAware (org.springframework.context)
使用方法如下
@Component
public class UserService implements ApplicationContextAware {
public ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
3、动态加载bean
3.1 Profile
Spring提供可以根据当前环境,动态的激活和切换一系列bean的功能
默认是default环境
修改profile 环境的方法
-
使用命令行参数
-Dspring.profiles.active=dev // 默认是default
-
通过spring的无参构造方法,手动设置profile
代码如下
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.getEnvironment().setActiveProfiles("test"); context.register(BeanProfileConfig.class); context.refresh();
修改后,使用@Profile的方法,代码如下(@profile也可以写在类上,则表示控制类里面所有的@bean)
@Bean
@Profile("dev")
public DataSource dataSourceDev(@Value("${db.password}") String pwd) throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
return dataSource;
}
3.2 Conditional 注解按条件注入
@Conditional :表示按照一定的条件去注册bean springBoot 中解决自动装配
@Conditional({YourCondition.class})
新建类->实现Condition接口->完成实现方法。将这个类作为参数传入@Condition
@Condtional参数既可以作用在方法上1 (与@Bean共同出现) 也可以作用在类上2(与@Configuration同时出现)
作用分别为
1、判断是否创建某个bean
2、判断是否创建这个configuration下面的所有bean
浙公网安备 33010602011771号