1.Bean生命周期
2.bean后处理器
1.@Autowired、@Resource、@PostConstruct、@PreDestroy、@Value如何被解析的?
public class Bean2 {
private Bean1 bean1;
@Autowired
public void setBean1(Bean1 bean1) {
System.out.println("@Autowired生效" + bean1);
this.bean1 = bean1;
}
@Resource
public void setPort(@Value("${java.version}")String version){
System.out.println("@Value生效" + version);
}
@PostConstruct
public void init() {
System.out.println("PostConstruct生效");
}
@PreDestroy
public void destroy() {
System.out.println("PreDestroy生效");
}
}
public class A04Application {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("bean1",Bean1.class);
context.registerBean("bean2",Bean2.class);
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.refresh();
context.close();
}
}
2.@ConfigurationProperties
@ConfigurationProperties(prefix = "java")
public class Bean1 {
private String version;
private String home;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
@Override
public String toString() {
return "Bean1{" +
"version='" + version + '\'' +
", home='" + home + '\'' +
'}';
}
}
public class A04Application {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("bean1",Bean1.class);
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
context.refresh();
System.out.println(context.getBean("bean1"));
context.close();
}
}
3.AutowiredAnnotationBeanPostProcessor运行分析
public class AutowiredApplication {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean1",new Bean1());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean2 bean2 = new Bean2();
System.out.println(bean2);
processor.postProcessProperties(null,bean2,"bean2");
System.out.println(bean2);
}
}
public class AutowiredApplication {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean1",new Bean1());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean2 bean2 = new Bean2();
Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean2", Bean2.class, null);
System.out.println(metadata);
metadata.inject(bean2,"bean2",null);
System.out.println(bean2);
Field bean3 = Bean2.class.getDeclaredField("bean3");
DependencyDescriptor descriptor = new DependencyDescriptor(bean3, false);
Object o = beanFactory.doResolveDependency(descriptor, null, null, null);
System.out.println(o);
}
}
3.常见的bean工厂后处理器
1.工厂后置处理器模拟实现---->ComponentScan
public class A05Application {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (componentScan != null){
for (String p : componentScan.basePackages()) {
String path = "classpath*:"+p.replace(".","/")+"/**/*.class";
System.out.println(path);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
MetadataReader reader = factory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
if (annotationMetadata.hasAnnotation(Component.class.getName())
|| annotationMetadata.hasMetaAnnotation(Component.class.getName())){
AbstractBeanDefinition bd = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
String name = generator.generateBeanName(bd, beanFactory);
beanFactory.registerBeanDefinition(name,bd);
}
}
}
}
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
context.close();
}
}
@Configuration
@ComponentScan(basePackages = "com.liubo.spring.a05.component")
public class Config {
}
2.工厂后置处理器模拟实现---->@Bean
public class A05Application {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/liubo/spring/a05/Config.class"));
Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
System.out.println(method);
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.setFactoryMethodOnBean(method.getMethodName(),"config");
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
if (initMethod.length() >0){
builder.setInitMethodName(initMethod);
}
AbstractBeanDefinition bd = builder.getBeanDefinition();
context.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(),bd);
}
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
context.close();
}
}
@Configuration
public class Config {
@Bean
public Bean1 getBean1() {
return new Bean1();
}
public Bean2 getBean2() {
return new Bean2();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean(initMethod = "init")
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/dreammall_pms?characterEncoding=utf-8&serverTimezone=GMT%2B8");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setDriver(new DruidDriver());
return dataSource;
}
}
3.工厂后置处理器模拟实现----->Mapper
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
try {
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath*:com/liubo/spring/a05/mapper/**/*.class");
for (Resource resource : resources) {
MetadataReader reader = factory.getMetadataReader(resource);
ClassMetadata metadata = reader.getClassMetadata();
if (metadata.isInterface()) {
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(metadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
AbstractBeanDefinition bdName = BeanDefinitionBuilder.genericBeanDefinition(metadata.getClassName()).getBeanDefinition();
String beanName = generator.generateBeanName(bdName, registry);
registry.registerBeanDefinition(beanName,bd);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}