@Overridepublic Object postAfterProcessor(String beanName, Object bean) { System.out.println("初始化后的bean:" + beanName + " -- " + bean); if (beanName.equals("userService")) { // 创建一个代理对象, 代理的是UserInterface这个 Object proxyInstance = Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override /** * proxy:代理对象 * method:代理对象当前正在执行的方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("切面逻辑"); return method.invoke(bean, args); } }); return proxyInstance; } return bean;}源码备注springLydApplicationContextpublic class LydApplicationContext { private Class configClass; // 注入的配置类 private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); // key是component名字 private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>(); // 单例池 private ArrayList<BeanPostProcessor> beanPostProcessorList = new ArrayList<>(); // 记录BeanPostProcessor,在扫描的时候判断,使用 public LydApplicationContext(Class configClass) { // 构造方法 this.configClass = configClass; // spring容器创建之后 // 1 扫描 // 通过配置文件的注解获取扫描路径 if (configClass.isAnnotationPresent(ComponentScan.class)) { ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class); // 1.1 扫描路径:只是个包名,扫描的是java的class文件,而并非源文件 , com.lyd.service String path = componentScanAnnotation.value(); // 1.2 将路径文件替换成/的形式 path = path.replace(".","/"); // 1.3 通过类加载器获取资源路径 ClassLoader classLoader = LydApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(path); // 1.4 转成文件形式 , 主要是为了获取他的绝对地址 File file = new File(resource.getFile());// System.out.println(file); if (file.isDirectory()) { // 如果是文件夹 File[] files = file.listFiles(); for (File f : files) { String absolutePath = f.getAbsolutePath(); // 获取绝对路径 System.out.println("绝对路径:" + absolutePath); // 1.5 对编译文件进行处理 if (absolutePath.endsWith(".class")) { // 判断是否为编译文件 /** * 需要拿到的是编译文件,通过类加载器去获取 * 需要将com\lyd\service\UserService转成com.lyd.service.UserService */ String className = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class")); className = className.replace("\\", "."); System.out.println("类名:" + className); try { // 1.6 通过全限定名使用类加载器获取类 (利用反射机制) Class<?> clazz = classLoader.loadClass(className); // 1.7 在通过这个clazz(类)来判断是否有component注解,有则是bean if (clazz.isAnnotationPresent(Component.class)) { // 6 判断是否是并加入beanPostProcessorList,这里不能使用instanceof if (BeanPostProcessor.class.isAssignableFrom(clazz)) { // 直接生成对象 BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance(); // 然后保存进去 beanPostProcessorList.add(instance); } Component annotation = clazz.getAnnotation(Component.class); String beanName = annotation.value(); // * 默认生成bean,如果只使用Component注解,没有写上beanName的值,那么就需要自动生成 if (beanName.equals("")) { // 默认开头小字母 beanName = Introspector.decapitalize(clazz.getSimpleName()); } /** * 這就是一个bean了 * 然而在这里并不是直接就创建bean了 , bean分为了单例bean和多例bean */ BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setType(clazz); if (clazz.isAnnotationPresent(Scope.class)) { // 判断是单例还是多例 Scope scope = clazz.getAnnotation(Scope.class); beanDefinition.setScope(scope.value()); } else { beanDefinition.setScope("singleton"); } beanDefinitionMap.put(beanName, beanDefinition); } } catch (Exception e) { e.printStackTrace(); } } } } } // 2 创建单例bean对象 for (String beanName : beanDefinitionMap.keySet()) { BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if (beanDefinition.getScope().equals("singleton")) { // 那么,如何保证单例呢?就需要有个单例池,singletonObjects Object bean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, bean); // 将单例bean存到单例池中 } } } // 创建bean private Object createBean(String beanName, BeanDefinition definition) { // 利用反射获取实例,采用无参构造方法 Class clazz = definition.getType(); // 通过无参构造方法获取实例 try { Object instance = clazz.getConstructor().newInstance(); // 到这里直接返回,bean的对象也就创建完成 // 3 依赖注入 for (Field field : clazz.getDeclaredFields()) { // 判断字段上是否存在Autowried注解 if (field.isAnnotationPresent(Autowired.class)) { /** * 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查 。 * 值为 false 则指示反射的对象应该实施 Java 语言访问检查; * 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问 ; */ field.setAccessible(true); // 反射需要设置这个 , 不然无法赋值 // 用其属性名,这就意味着private RoleService roleService;roleService不能乱取 field.set(instance, getBean(field.getName())); } } // * instanceof:是针对某个对象去判断是否实现某个类 // 4 Aware回调机制 if (instance instanceof BeanNameAware) { ((BeanNameAware)instance).setBeanName(beanName); } // 6 BeanPostProcessor 初始化前 AOP 遍历beanPostProcessorList for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postBeforeProcessor(beanName, instance); } // 5 初始化 if (instance instanceof InitializingBean) { ((InitializingBean)instance).afterPropertiesSet(); } // 6 BeanPostProcessor 初始化后 AOP for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postAfterProcessor(beanName, instance); } return instance; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } // 获取bean对象 public Object getBean(String beanName) { BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if (beanDefinition == null) { throw new NullPointerException("找不到bean名字为[" + beanName + "]的bean对象"); } else { // 找到就做相应的操作 String scope = beanDefinition.getScope(); if (scope.equals("singleton")) { // 通过单例池获取 Object bean = singletonObjects.get(beanName); if (bean == null) { // 单例池中如果没有bean,就需要去创建 bean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, bean); } return bean; } else { // 多例的就不需要记录,每次都是通过创建 return createBean(beanName, beanDefinition); } } }}
推荐阅读
- 【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
- 基础版 【网络】内网穿透方案&FRP内网穿透实战
- FGO日服七周年礼装自选哪个好
- 蚂蚁庄园今日答题答案是什么
- iqooneo5是什么屏幕_iqooneo5屏幕尺寸参数
- 原神如何去雷神的岛屿(原神如何上雷神岛)
- 一次SpringBoot版本升级,引发的血案
- 中 学习ASP.NET Core Blazor编程系列十——路由
- 小米11和vivox60哪个好_小米11和vivox60参数对比
- 苹果13mini屏幕多大尺寸_苹果13mini屏幕尺寸