代码结构:
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(); }
结果: