Bean的生命周期
0,调用BeanFactoryPostProcessor的postProcessBeanFactory方法
1,调用Bean的构造函数(或者工厂方法)实例化Bean.
2,对Bean的成员变量赋值.
3,如果Bean实现了BeanNameAware,调用Bean的setBeanName方法.
4,如果Bean实现了BeanFactoryAware,调用Bean的setBeanFactory方法.
5,如果Bean实现了ApplicationContextAware,调用Bean的setApplicationContext方法.
6,如果容器中配置了BeanPostProcessor,调用BeanPostProcessor的postProcessBeforeInitialization方法(如果有多个,调用每一个)
6,如果Bean实现了InitializingBean,调用Bean的afterPropertiesSet方法.
7,如果Bean配置了init-method方法,调用init-method配置的Bean方法.
8,如果容器中配置了BeanPostProcessor,调用BeanPostProcessor的postProcessAfterInitialization方法.(如果有多个,调用每一个)
9,Bean处于可以使用的状态.
10,Spring容器关闭.
11,如果Bean实现了DisposableBean,调用Bean的destroy方法.
12,如果Bean配置了destroy-method方法,调用destroy-method配置的Bean的方法.
Bean
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* 测试生命周期的Bean
*/
public class StudentBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {
private String name;
private int age;
private String beanName;//实现了BeanNameAware接口,Spring可以将BeanName注入该属性中
private BeanFactory beanFactory;//实现了BeanFactory接口,Spring可将BeanFactory注入该属性中
public StudentBean(){
System.out.println("【Bean构造方法】学生类的无参构造方法");
}
@Override
public String toString() {
return "StudentBean{" +
"name='" + name + '\'' +
", age=" + age +
", beanName='" + beanName + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【set注入】注入学生的name属性");
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("【set注入】注入学生的age属性");
this.age = age;
}
/**
* 自己编写的初始化方法
*/
public void myInit(){
System.out.println("【init-method】调用init-method属性配置的初始化方法");
}
/**
* 自己编写的销毁方法
*/
public void myDestroy(){
System.out.println("【destroy-method】调用destroy-method属性配置的销毁方法");
}
/**
* BeanFactoryAware接口的方法
* @param beanFactory
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware的setBeanFactory方法得到beanFactory引用");
}
/**
* BeanNameAware接口的方法
* @param name
*/
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("【BeanNameAware接口】调用BeanNameAware的setBeanName方法得到Bean的名称");
}
/**
* InitializingBean接口的方法
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用InitializingBean接口的afterPropertiesSet方法");
}
/**
* DisposableBean接口的方法
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("【DisposableBean接口】调用DisposableBean接口的destroy方法");
}
}
BeanPostProcessor接口
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor(){
System.out.println("【BeanPostProcessor接口】调用BeanPostProcessor的构造方法");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor接口】调用postProcessBeforeInitialization方法,这里可对"+beanName+"的属性进行更改。");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【BeanPostProcessor接口】调用postProcessAfterInitialization方法,这里可对"+beanName+"的属性进行更改。");
return bean;
}
}
BeanFactoryPostProcessor接口
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println("【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor实现类构造方法");
}
/**
* 重写BeanFactoryPostProcessor接口的postProcessBeanFactory方法,可通过该方法对beanFactory进行设置
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
System.out.println("【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法");
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("studentBean");
beanDefinition.getPropertyValues().addPropertyValue("age", "21");
}
}
Spring配置文件beans.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!--配置Bean的后置处理器-->
<bean id="beanPostProcessor" class="com.xxx.cyclelife.MyBeanPostProcessor">
</bean>
<!--配置BeanFactory的后置处理器-->
<bean id="beanFactoryPostProcessor" class="com.xxx.cyclelife.MyBeanFactoryPostProcessor">
</bean>
<bean id="studentBean" class="com.xxx.cyclelife.StudentBean" init-method="myInit"
destroy-method="myDestroy" scope="singleton">
<property name="name" value="xxx"></property>
<property name="age" value="21"></property>
</bean>
</beans>
常用注解
@Autowire和@Resource
共同点:
均可标注在字段或属性的setter方法上。
都可以通过@Qualifier显式指定 autowired by qualifier name。
区别:
@Autowired是spring的注解,使用AutowiredAnnotationBeanPostProcessor处理依赖注入。
@Resource来自于JSR-250位于java.annotation包,使用CommonAnnotationBeanPostProcessor处理依赖注入。
@Autowired默认 autowired by type,如果失败,则退化为autowired by field name;
@Resource默认autowired by field name,如果失败,则退化为autowired by type。可以使用@Autowired + @Qualifier实现@Resource的效果。
@Autowired有个required属性,配置为false时如果没有找到对应的bean是不会抛异常的。@Resource没有该配置,找不到会抛异常。
@Component和@Service、@Repository、@Controller
使用@Component注解标识类会生成响应的bean,默认的名称(id)是小写开头的非限定类名。也可以指定名称:@Component(“hello”),不推荐使用。
@Controller对应控制层的Bean,@Service对应的是业务逻辑层Bean,@Repository对应数据访问层也就是持久层的Bean。和@Component是等效的,区别在于后三个有具体的业务含义,分别对应web架构的3个分层。推荐使用后三者代替@Component,在spring未来的版本中,@Controller,@Service,@Repository会携带更多语义。并且便于开发和维护。
@Qualifier
当容器中存在同样类型的多个bean时,用@Qualifier注解指定注入Bean的名称 。
@ComponentScan
自动扫描包名下所有声明为Bean的类
@EnableAspectJAutoProxy
开启Spring对AspectJ的支持
@Bean
注解在方法上,声明当前方法的返回值为一个Bean
@PostConstruct
在构造函数执行完后执行
@PreDestroy
在Bean销毁之前执行
AOP注解(链接git)
@Aspect //声明为切面
@PointCut //切点,定义拦截规则
@After
@Before
@Around
@Conditional
这个注解会检查条件,只有这个条件满足的时候,才会enable某些配置
标注在类上,声明配置类,相当于把该类作为spring的xml配置文件中的来使用。
@ConditionalOnClass
当classpath里面有一个或几个指定的类的时候才激活一个配置
@ConditionalOnMissingBean
当一个bean没有创建的时候,创建一个bean
@ConditionalOnBean
@ConditionalOnExpression
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnResource
@ConditionalOnWebApplication
@EnableXXX
使用@Import注解来做了一个简单的configuration import
@EnableTransactionManagement
启用了声明式的事务管理
@EnableWebMvc
启用Spring MVC
@EnableScheduling
初始化一个定时器。
@EnableConfigurationProperties
自动把一个POJO映射到一个Spring Boot配置文件(默认的是application.properties)里面的属性列表
@Import和@ImportResource
全局句柄
package com.oppo.push.inbox.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Lazy(false)
@Component()
public class ApplicationContextHolder implements ApplicationContextAware {
private final static Logger log = LoggerFactory.getLogger(ApplicationContextHolder.class);
private ApplicationContextHolder(){}
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextHolder.applicationContext = applicationContext;
log.info("spring applicationContext init");
}
public static ApplicationContext getApplicationContext() {
if(applicationContext == null)
throw new IllegalStateException("'applicationContext' property is null,ApplicationContextHolder not yet init.");
return applicationContext;
}
}
其他
https://www.cnblogs.com/liaojie970/p/8042686.html
https://www.cnblogs.com/duanxz/p/7493276.html
https://www.cnblogs.com/kungfupanda/p/7747004.html
未完待续