zoukankan      html  css  js  c++  java
  • Spring-模拟BeanPostProcessor

    代码结构:

    package com.java.spring;
    
    import org.springframework.beans.BeansException;
    
    public interface IBeanPostProcessor {
    
        Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException;
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }
    package com.java.service;
    
    public interface IOrderService {
        void doOrder();
    }
    package com.java.service;
    
    import com.java.spring.CustomizeComponent;
    import com.java.spring.IBeanNameAware;
    
    @CustomizeComponent("orderService")
    public class OrderService implements IBeanNameAware,IOrderService {
    
        private String beanName;
    
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
        }
    
        public void doPBeanName(){
            System.out.println(">>>>"+beanName);
        }
    
    
        @Override
        public void doOrder() {
            System.out.println("do order........");
        }
    }
    package com.java.service;
    
    import com.java.spring.CustomizeAutowired;
    import com.java.spring.CustomizeComponent;
    import com.java.spring.CustomizeScope;
    import com.java.spring.IInitializingBean;
    
    @CustomizeComponent("userService")
    @CustomizeScope("prototype")
    public class UserServiceImpl implements IInitializingBean {
    
        private String name;
    
        @CustomizeAutowired
        public OrderService orderService;
    
        public void doSomething(){
            System.out.println("测试 BeanPostProcessor.....,name="+name);
            orderService.doPBeanName();
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("哈哈,我做了坏事.........");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    package com.java.spring;
    
    import java.io.File;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 定制的Spring
     *  CustomizeComponentScan -->扫描路径-->获取Component注解-->CustomizeBeanDefinition-->放入beanDefinitionMap
     *
     */
    public class CustomizeApplicationContext {
        private Class customizeConfig;
    
        /**
         * 单例池
         */
        private ConcurrentHashMap<String,Object> singleTonMap = new ConcurrentHashMap<>();
    
        /**
         * bean定义Map
         */
        private ConcurrentHashMap<String,CustomizeBeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    
        private List<IBeanPostProcessor> beanPostProcessorList = new ArrayList();
    
        public CustomizeApplicationContext(Class customizeConfig) {
            this.customizeConfig = customizeConfig;
            scan();
            initAllSingleBean();
        }
    
    
        /**
         * CustomizeComponentScan -->扫描路径-->获取Component注解-->CustomizeBeanDefinition-->放入beanDefinitionMap
         */
        private void scan(){
            //获取传入配置类注解
            CustomizeComponentScan ccscan =
                    (CustomizeComponentScan) this.customizeConfig.getDeclaredAnnotation(CustomizeComponentScan.class);
    
            //获取扫描路径
            String scanPath = ccscan.value();
            //将路径转换成 com.xx->com/xx
            String dotScanPath = scanPath.replace(".", "//");
    
            //找到扫描路径下所有文件
            //注意:这里不能用 CustomizeApplicationContext.class.getResource("com/java/service")
            //原因是我们需要获取的是工程所在的路径
            ClassLoader classLoader = CustomizeApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(dotScanPath);
            File file = new File(resource.getFile());
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File f : files) {
                    String fileName = f.getName();
                    if (fileName.endsWith(".class")) {
                        try {
                            //获取扫描路径下的class
                            Class<?> aClass = classLoader.loadClass(subFilePath(f.getPath()));
    
                            if(aClass.isAnnotationPresent(CustomizeComponent.class)){
    
    
                                //模拟Spring  BeanPostProcessor实现
                                if(IBeanPostProcessor.class.isAssignableFrom(aClass)){
                                    //注意:判断类是否实现了 IBeanPostProcessor 接口
                                    //注意:spring 源码不是下面实现
                                    IBeanPostProcessor instance = (IBeanPostProcessor) aClass.getDeclaredConstructor().newInstance();
    
                                    //存放起来,方便初始化前后做操作
                                    beanPostProcessorList.add(instance);
                                }
    
    
                                //如果是自定义的注解,做自己想做的
                                CustomizeComponent ccp = aClass.getDeclaredAnnotation(CustomizeComponent.class);
                                String beanName =  ccp.value();
    
                                //判断是否是单例
                                CustomizeBeanDefinition beanDefinition = new CustomizeBeanDefinition();
                                if(aClass.isAnnotationPresent(CustomizeScope.class)){
                                    CustomizeScope customizeScope = aClass.getDeclaredAnnotation(CustomizeScope.class);
                                    beanDefinition.setScope(customizeScope.value().trim());
                                }else{
                                    //如果不设置,默认单例
                                    beanDefinition.setScope("singleton");
                                }
                                beanDefinition.setClazz(aClass);
    
                                beanDefinitionMap.put(beanName,beanDefinition);
                            }
    
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (NoSuchMethodException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        /**
         * 初始化所有单例bean
         */
        private void initAllSingleBean(){
            for(Map.Entry<String,CustomizeBeanDefinition> entry : beanDefinitionMap.entrySet()){
                String beanName = entry.getKey();
                CustomizeBeanDefinition beanDefinition =  entry.getValue();
                if("singleton".equals(beanDefinition.getScope())){
                    Object beanObj = createBean(beanName,beanDefinition);
                    singleTonMap.put(beanName,beanObj);
                }
            }
        }
    
        /**
         * 截取路径
         *
         * @param absFilePath
         * @return
         */
        private String subFilePath(String absFilePath) {
            if (null == absFilePath) {
                return "";
            }
    
            String subPath = absFilePath.substring(absFilePath.indexOf("com"), absFilePath.indexOf(".class"));
    
            if (subPath.length() > 0) {
                subPath = subPath.replace(File.separator, ".");
            }
            return subPath;
        }
    
        /**
         * 创基bean
         * @param beanName
         * @return
         */
        public Object createBean(String beanName,CustomizeBeanDefinition beanDefinition){
            Class clazz = beanDefinition.getClazz();
            Object instance = null;
    
            try {
                instance = clazz.getDeclaredConstructor().newInstance();
    
                //依赖注入,给属性赋值
                //获取类中所有属性
                Field[] filelds = clazz.getDeclaredFields();
                for(Field f : filelds){
                    //如果有定义的注入注解
                    if(f.isAnnotationPresent(CustomizeAutowired.class)){
                        //根据属性名去找
                        String fBeanName = f.getName();
    
                        Object fBean = getBean(fBeanName);
                        CustomizeAutowired customizeAutowired = f.getDeclaredAnnotation(CustomizeAutowired.class);
                        if(customizeAutowired.required() && null == fBean){
                            //如果是必须
                            throw new NullPointerException();
                        }
    
                        //由于属性为私有属性,需要通过反射方式赋值,故设置true
                        f.setAccessible(true);
                        //将对象赋值给属性
                        f.set(instance,fBean);
                    }
                }
    
    
                //Aware 回调
                if(instance instanceof IBeanNameAware){
                    ((IBeanNameAware) instance).setBeanName(beanName);
                }
    
                //模拟Spring BeanPostProcessor初始化前操作
                for(IBeanPostProcessor beanPostProcessor : beanPostProcessorList){
                    beanPostProcessor.postProcessBeforeInitialization(instance,beanName);
                }
    
    
                //初始化操作
                if(instance instanceof IInitializingBean){
                    ((IInitializingBean) instance).afterPropertiesSet();
                }
    
                //模拟Spring BeanPostProcessor初始后前操作,是创建对象的最后一步
                for(IBeanPostProcessor beanPostProcessor : beanPostProcessorList){
                    beanPostProcessor.postProcessAfterInitialization(instance,beanName);
                }
    
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return instance;
        }
    
        /**
         * 获取bean 对象
         *
         * @param name
         * @return
         */
        public Object getBean(String name) {
            if(beanDefinitionMap.containsKey(name)){
                CustomizeBeanDefinition beanDefinition = beanDefinitionMap.get(name.trim());
    
                if("singleton".equals(beanDefinition.getScope())){
                    //如果是单例,从单例池中返回
                    return singleTonMap.get(name);
                }else{
                    //原型模式,创建bean对象
                    return createBean(name,beanDefinition);
                }
            }else{
                //不存在bean,可自定义异常
                throw new NullPointerException();
            }
        }
    }
    package com.java.service;
    
    import com.java.spring.CustomizeComponent;
    import com.java.spring.IBeanPostProcessor;
    import org.springframework.beans.BeansException;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 定制创建bean 前后处理
     *
     *  注意:通常利用BeanPostProcessor在创建bean前后搞事情
     */
    @CustomizeComponent
    public class CustomizeBeanPostProcessor implements IBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化前.........");
            if("userService".equals(beanName)){
                ((UserServiceImpl) bean).setName("南风不竞");
            }
    
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化后.........");
    
            //AOP 其实在BeanProcessor 后置方法中实现
            if("orderService".equals(beanName)){
                //JDK 代理,也可以用cglib方式代理(不用另外写接口了)
                Object instance = Proxy.newProxyInstance(CustomizeBeanPostProcessor.class.getClassLoader(),bean.getClass().getInterfaces(), (proxy, method, args) -> {
    
                    //注意:找切点,匹配的实现AOP 注解的方法等
                    System.out.println("代理逻辑..............");
                    return method.invoke(bean,args);
                });
    
                return instance;
            }
            return bean;
        }
    }

    测试:

       public static void main(String[] args) {
            SpringLoader loaderTest = new SpringLoader();
            loaderTest.test2();
        }
    
        /**
         * 依赖注入测试
         */
        private void test2(){
            CustomizeApplicationContext context = new CustomizeApplicationContext(CustomizeConfig.class);
            UserServiceImpl userService1 = (UserServiceImpl) context.getBean("userService");
            userService1.doSomething();
        }

    结果:

  • 相关阅读:
    百度网盘提速方法
    2020年北京某企Java校招真题
    scrapy中选择器的用法
    scrapy框架基础篇
    selenium模拟浏览器爬取淘宝产品信息
    python连接MongoDB
    pyquery库
    BeautifulSoup4库
    Locust
    【Java】类赋值的使用方式
  • 原文地址:https://www.cnblogs.com/xiaozhuanfeng/p/14726824.html
Copyright © 2011-2022 走看看