一、BeanNameAware
BeanNameAware 提供了setBeanName方法,可知道在spring bean factory中的bean name.
通常不推荐一个对象依赖于它的bean的名字
@Component("accountTest")
public class Account implements BeanNameAware{
private String beanName;
public void setBeanName(String name) {
System.out.println("bean name is : " + name);
this.beanName=name;
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Account account = context.getBean(Account.class);
}
//Result: bean name is : accountTest
二、BeanFactoryAware
继承这个接口是为了得到BeanFactory的引用,进而得到想要的Bean。但是这样做是违反DI注入原则的,所以Spring是不建议这样做的。
@Component("accountTest")
public class Account implements BeanFactoryAware {
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory is : " + beanFactory );
this.beanFactory=beanFactory;
}
public Object getBean(String beanName){
if(beanFactory != null){
return beanFactory.getBean(beanName);
}
return null;
}
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Account account = context.getBean(Account.class);
System.out.println(account.getBean("accountTest"));
}
/**result:
beanFactory is : org.springframework.beans.factory.support.DefaultListableBeanFactory@5c7fa833: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,springConfig,accountTest,accountService]; root of factory hierarchy
com.springlearning.entity.Account@f0f2775
**/
三、InitializingBean,init-method和@PostConstruct
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
四、DisposableBean,destory-method和@PreDestory
public class Account implements InitializingBean, DisposableBean {
private String beanName;
private BeanFactory beanFactory;
public void afterPropertiesSet() throws Exception {
System.out.println("init");
}
public void destroy() throws Exception {
System.out.println("destory");
}
/**
@PostConstruct
public void init() throws Exception {
System.out.println("init");
}
@PreDestroy
public void destroy() throws Exception {
System.out.println("destory");
}
**/
public void test(){
System.out.println("test method");
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Account account = context.getBean(Account.class);
account.test();
context.registerShutdownHook();
}
结果:
init
test method
destory
五、BeanFactoryPostProcessor,BeanPostProcessor 和 InstantiationAwareBeanPostProcessor
BeanFactoryPostProcessor: 实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。
BeanPostProcessor: 实现该接口,可以在Bean(实例化之后)初始化的前后做一些自定义的操作,但是拿到的参数只有BeanDefinition实例和BeanDefinition的名称,也就是无法修改BeanDefinition元数据:
他们都是spring的后置处理器,当有多个是可实现Ordered接口getOrder方法,该方法返回一整数,默认值为 0,优先级最高,值越大优先级越低。
应用场景
几个典型的应用如:
1、解析bean的注解,将注解中的字段转化为属性
2、统一将属性在执行前,注入bean中,如数据库访问的sqlMap,如严重服务,这样不需要每个bean都配置属性
3、打印日志,记录时间等。
InstantiationAwareBeanPostProcessor: