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();
    }

结果:

原文地址:https://www.cnblogs.com/xiaozhuanfeng/p/14726824.html