bean处理器、bean工厂处理器

1.Bean生命周期

  • 构造器
  • 依赖注入
  • 初始化
  • 销毁

image-20221225125716171

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()); // @value生效

        context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // @Autowire @Value
        context.registerBean(CommonAnnotationBeanPostProcessor.class); // @Resource @PostConstruct @PreDestroy
        // 初始化容器
        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()); // @Value
        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"); // 依赖注入 @Autowired @Value
        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()); // @Value
        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); //获取bean
        System.out.println(metadata);

        // 调用InjectionMetadata来进行依赖注入,注入时按类型查找
        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工厂后处理器

image-20221225155707265

1.工厂后置处理器模拟实现---->ComponentScan

public class A05Application {
    
    
    public static void main(String[] args) throws IOException {
    
    
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("config",Config.class);
//        context.registerBean(ConfigurationClassPostProcessor.class); // @ComponentScan @Bean @Import @ImportResource
//        context.registerBean(MapperScannerConfigurer.class,bd -> {   //MapperScan
//            bd.getPropertyValues().add("basePackage","com.liubo.spring.a05.component");
//        });
        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);
            // 判断Bean上是否加了init
            String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();

            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
            // 定义工厂方法 是config的工厂方法
            builder.setFactoryMethodOnBean(method.getMethodName(),"config");
            // 指定自动装配模式,默认NO:没有找到就跳过 如果不加sqlSessionFactoryBean(DataSource dataSource)会报错
            builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);

            if (initMethod.length() >0){
    
    
                builder.setInitMethodName(initMethod);
            }
            // 加入bean工厂
            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

image-20221229212318227

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)
                            // 给MapperFactoryBean构造方法参数
                            .addConstructorArgValue(metadata.getClassName())
                            // 自动装配根据类型
                            .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
                            .getBeanDefinition();
                    // spring的做法,获取beanName,如果使用bd作为bean名称的话  2个接口的beanName都会是一样的 后者会覆盖前者
                    AbstractBeanDefinition bdName = BeanDefinitionBuilder.genericBeanDefinition(metadata.getClassName()).getBeanDefinition();
                    String beanName = generator.generateBeanName(bdName, registry);
                    registry.registerBeanDefinition(beanName,bd);
                }
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

image-20221229212419539

猜你喜欢

转载自blog.csdn.net/weixin_53060535/article/details/128512599