原生的Spring框架除了IOC还有个强大的功能---AOP
之所以出现AOP,对原本的类没有任何侵入性的情况下还可以对它进行自定义逻辑。
首先要明白AOP在Spring的生命周期里的哪一步去做的,做了什么。
生命周期里的哪一步去做的:时间点是初始化后做的。
做了什么:生成一个代理类,把这个代理类放到容器里替你做事。
此处是用JDK的动态代理(JDK的动态代理有一个特点就是这个被代理的对象必须实现一个接口才能给这个对象生成代理对象)
第一步:写一个接口让类重写接口方法
public interface YuWenWenServiceIfa {
void test();
}
@Component("yuWenWenService")
public class YuWenWenService implements YuWenWenServiceIfa {
@Autowired
private MiaoWenWenService miaoWenWenService;
public String beanName;
public void test() {
System.out.println(miaoWenWenService);
System.out.println(beanName);
}
}
第二步:JDK生成动态代理对象(此处也可用Cglib动态代理)
Proxy.newProxyInstance方法参数一共有三个,类加载器,接口,invocationHandler
其中invocationHandler是一个函数式接口(既然是函数式接口就可以Lamda)
Proxy.newProxyInstance(YuWenWenApplicationContext.class.getClassLoader(), bean.getClass().getInterfaces(),
(Object p, Method m, Object[] a) -> {
System.out.println("代理逻辑前");
Object c=m.invoke(bean,a);
System.out.println("代理逻辑前");
return c;
});
第三步:在初始化后做动态代理逻辑
@Override
public Object postProcessAfterInitialization(Object bean) {
System.out.println("后置处理器,初始化后");
if (bean.getClass() == YuWenWenService.class) {
Object proxy = Proxy
.newProxyInstance(YuWenWenApplicationContext.class.getClassLoader(), bean.getClass().getInterfaces(),
(Object p, Method m, Object[] a) -> {
System.out.println("代理逻辑前");
Object c=m.invoke(bean,a);
System.out.println("代理逻辑后");
return c;
});
return proxy;
}
return bean;
}
测试:注意一下,因为容器里面不是YuWenWenService这个对象了 而是他的代理对象YuWenWenServiceIfa
public class ApplicationTest {
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
YuWenWenApplicationContext yuWenWenApplicationContext = new YuWenWenApplicationContext(AppConfig.class);
YuWenWenServiceIfa yuWenWenService = (YuWenWenServiceIfa) yuWenWenApplicationContext.getBean("yuWenWenService");
yuWenWenService.test();
}
}
成功
代理逻辑前
com.sbi.service.MiaoWenWenService@3b764bce
null
代理逻辑后
源码奉上
package com.sbi.config;
import com.sbi.annotation.Autowired;
import com.sbi.annotation.Component;
import com.sbi.annotation.ComponentScan;
import com.sbi.annotation.Scope;
import com.sbi.service.BeanPostProcessor;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
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;
public class YuWenWenApplicationContext {
private Class config;
// 单例池(key:beanName,value:bean)
private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
// BeanDefinitionMap(key:beanName,value:类描述)
private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
// BeanPostProcessorList
private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();
public YuWenWenApplicationContext(Class config)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
this.config = config;
// 扫描bean,并且得到所有beanDefinition放在beanDefinitionMap里
scan(config);
// 循环beanDefinitionMap全部
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
if (entry.getValue().getScope().equals("singleton")) {
// 创建bean
Object bean = createBean(entry.getValue());
// 将创建好的bean放到单例池等待getBean调用
singletonObjects.put(entry.getKey(), bean);
}
}
}
private Object createBean(BeanDefinition beanDefinition)
throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 第一步:创建对象
Object o = beanDefinition.getClazz().getDeclaredConstructor().newInstance();
// 第二部:依赖注入
// 先通过反射拿到这个对象的私有属性
Field[] declaredFields = o.getClass().getDeclaredFields();
// 遍历私有属性
for (Field field : declaredFields) {
// 判断私有属性的是否持有@Autowired
if (field.isAnnotationPresent(Autowired.class)) {
// 如果持有@Autowired 就从单例池里拿这个bean并赋值
Object bean = getBean(field.getName());
// 默认是不允许设置私有属性的值的 此处必须得改成true
field.setAccessible(true);
// 实现依赖注入
field.set(o, bean);
}
}
// 第三步:Aware回调以及初始化方法
if (o instanceof BeanNameAware) {
((BeanNameAware) o).setBeanName();
}
// 第四步:BeanPostProcessor的前置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessBeforeInitialization(o);
}
// 第五步:初始化方法
if (o instanceof InitializingBean) {
((InitializingBean) o).afterPropertiesSet();
}
// 第六步:BeanPostProcessor的后置方法
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
o = beanPostProcessor.postProcessAfterInitialization(o);
}
return o;
}
private void scan(Class config)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 此处得到@ComponentScan的扫描路径
ComponentScan path = (ComponentScan) config.getDeclaredAnnotation(ComponentScan.class);
// 得到一个类加载器 classpath下面用AppClassLoader
ClassLoader classLoader = YuWenWenApplicationContext.class.getClassLoader();
// 得到类的包路径(此处为com.sbi.service格式需要改成com/sbi/service)
URL resource = classLoader.getResource(path.value().replace(".", "/"));
// 得到包下的文件
File file = new File(resource.getFile());
if (file.isDirectory()) {
// 得到包下所有的文件信息
File[] files = file.listFiles();
for (File f : files) {
String absolutePath = f.getAbsolutePath();
String pathReplaceBefore = absolutePath
.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
String pathreplaceAfter = pathReplaceBefore.replace("\\", ".");
// 此处最终需要com.sbi.service.YuWenWenService格式
Class<?> aClass = classLoader.loadClass(pathreplaceAfter);
// 如果这个类拥有@Component注解,那么我们就要反射
if (aClass.isAnnotationPresent(Component.class)) {
//扫描@Comptent注解发现有实现BeanPostProcessor的类
if (BeanPostProcessor.class.isAssignableFrom(aClass)) {
// 就将此类通过反射创建出来
BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.getDeclaredConstructor()
.newInstance();
// 将这个后置处理器加到list里
beanPostProcessorList.add(beanPostProcessor);
}
Component declaredAnnotation = aClass.getDeclaredAnnotation(Component.class);
// 拿到@Component的value值也就是bean的名字
String springbeanName = declaredAnnotation.value();
// 描述类创建
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(aClass);
// 判断这个类是否还持有@Scope的其他作用域(spring 一共有四种作用域,默认不指定的情况下就是单例)
if (aClass.isAnnotationPresent(Scope.class)) {
Scope declaredAnnotation1 = aClass.getDeclaredAnnotation(Scope.class);
beanDefinition.setScope(declaredAnnotation1.value());
} else {
// spring默认不指定的情况下就是单例作用域
beanDefinition.setScope("singleton");
}
// 将类信息放到beanDefinitionMap里
beanDefinitionMap.put(springbeanName, beanDefinition);
}
}
}
}
public Object getBean(String beanName)
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
//去beanDefinitionMap寻找是否有自己的类描述
if (beanDefinitionMap.containsKey(beanName)) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
//如果是单例bean,直接从单例池拿
if (beanDefinition.getScope().equals("singleton")) {
Object bean = singletonObjects.get(beanName);
return bean;
//如果是原型bean就给创建一个新的bean
} else {
Object bean = createBean(beanDefinition);
return bean;
}
//没招到的情况下就说明此类并没有加@Competent
} else {
throw new NullPointerException("此类不存在");
}
}
}