1.Aware和InitializingBean接口
-
Aware 接口用于注入一些与容器相关信息,例如
- BeanNameAware: 注入bean的名字
- BeanFactorAware: 注入beanFactor容器
- ApplicationContextAware: 注入applicationContext容器
- EmbeddedValueResolverAware: ${}
-
代码演示
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean { @Override public void setBeanName(String name) { System.out.println("当前bean" + this + "名字叫" + name); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("当前bean" + this + "容器是" + applicationContext); } @Override public void afterPropertiesSet() throws Exception { System.out.println("当前bean" + this + "初始化"); } @Autowired public void aaa(ApplicationContext applicationContext) { System.out.println("当前bean" + this + "使用@Autowired容器是" + applicationContext); } @PostConstruct public void bbb() { System.out.println("当前bean" + this + "使用@PostConstruct初始化"); } }
-
这些功能能用@Autowired实现,为什么要使用Aware接口呢?
- @Autowired的解析需要用到bean后处理器,属于扩展功能
- Aware接口属于内置功能,不加任务扩展,spring就能识别到
2.@Autowired失效分析
@Configuration
public class MyBean2 {
@Autowired
public void aaa(ApplicationContext applicationContext){
System.out.println("注入ApplicationContext");
}
@PostConstruct
public void bbb(){
System.out.println("初始化PostConstruct");
}
@Bean
public BeanFactoryPostProcessor processor1(){
return beanFactory -> {
System.out.println("执行 processor1");
};
}
}
-
发现@Autowired失效了 这是为什么呢?
-
而MyBean2的流程
3.spring初始化和销毁手段
- postConstruct 执行顺序也是这样
- 实现initializingBean接口
- @Bean(initMethod = “init3”)
4.Scope
1.scope的类型有哪些?
- singleton:容器中获取到的都是同一个bean
- prototype:每次去容器中获取到的bean都不一样
- request:与request域生命周期一样,请求来了会将bean创建出来放入request域中
- session:同一个会话,会话开始创建,会话结束销毁
- application:应用程序启动时bean创建,应用程序结束时bean被销毁
2.scope失效解决
- 单例打印3次发现F1都是同一个bean?这是为什么呢?
@Component
public class E {
@Autowired
@Lazy
private F1 f1;
// 2种方式
@Autowired
private ApplicationContext context;
public F1 getF1() {
return context.getBean(F1.class);
}
public F1 getF1() {
return f1;
}
}
@Component
@Scope("prototype")
public class F1 {
}
@ComponentScan("com.liubo.spring.a08")
public class A08Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A08Application.class);
E e = context.getBean(E.class);
System.out.println(e.getF1());
System.out.println(e.getF1());
System.out.println(e.getF1());
context.close();
}
}
-
原因与解决方法