文章目录
一、Bean的后置处理器
@Component
public class Test03 {
public static void main(String[] args) {
//GenericApplicationContext 是一个干净的容器
GenericApplicationContext context = new GenericApplicationContext();
//用原始方法注册三个bean
context.registerBean("bean1",Bean1.class);
context.registerBean("bean2",Bean2.class);
context.registerBean("bean3",Bean3.class);
context.registerBean("bean4",Bean4.class);
//解决@Value String问题
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
//@Autowired @Value
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
//@Resource @PostConstruct @PreDestroy
context.registerBean(CommonAnnotationBeanPostProcessor.class);
//@ConfigurationProperties
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
//初始化容器
context.refresh();
System.out.println(context.getBean(Bean4.class).toString());
//销毁容器
context.close();
}
}
class Bean1{
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2){
System.out.println("@Autowired生效");
this.bean2=bean2;
}
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3){
System.out.println("@Resource生效");
this.bean3=bean3;
}
private String javahome;
@Autowired
public void javahome(@Value("${JAVA_HOME}") String javahome){
System.out.println("@Value生效");
this.javahome=javahome;
}
@PostConstruct
public void post(){
System.out.println("@PostConstruct生效");
}
@PreDestroy
public void pre(){
System.out.println("@PreDestroy生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", javahome='" + javahome + '\'' +
'}';
}
}
class Bean2{
}
class Bean3{
}
@Data
@ConfigurationProperties(prefix = "java")
class Bean4{
private String home;
private String version;
}
二、@Autowired Bean后置处理器执行分析
@Component
public class Test03 {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//忽略创建过程、依赖注入、初始化
factory.registerSingleton("bean2",new Bean2());
factory.registerSingleton("bean3",new Bean3());
//@Value String类型
factory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
//${}的解析器
factory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
//查找哪些属性、方法加了@Autowired 这称之为 InjectionMetadata
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
Bean1 bean1 = new Bean1();
// System.out.println(bean1);
// //执行依赖注入 @Autowired @Value
// autowiredAnnotationBeanPostProcessor.postProcessProperties(null,bean1,"bean1");
// System.out.println(bean1);
//postProcessProperties步骤
Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
//获取bean1 上加了 @Value @Autowired 的成员变量,方法参数信息
InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);
//InjectionMetadata 来进行依赖注入,注入时按类型查找
metadata.inject(bean1,"bean1",null);
System.out.println(bean1);
//按照类型查找值
Field bean2 = Bean1.class.getDeclaredField("bean2");
DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(bean2, false);
Object o = factory.doResolveDependency(dependencyDescriptor, null, null, null);
System.out.println(o);
}
}
class Bean1{
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2){
System.out.println("@Autowired生效");
this.bean2=bean2;
}
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3){
System.out.println("@Resource生效");
this.bean3=bean3;
}
private String javahome;
@Autowired
public void javahome(@Value("${JAVA_HOME}") String javahome){
System.out.println("@Value生效");
this.javahome=javahome;
}
@PostConstruct
public void post(){
System.out.println("@PostConstruct生效");
}
@PreDestroy
public void pre(){
System.out.println("@PreDestroy生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", javahome='" + javahome + '\'' +
'}';
}
}
class Bean2{
}
class Bean3{
}
@Data
@ConfigurationProperties(prefix = "java")
class Bean4{
private String home;
private String version;
}