Aop原理
AOP原理其实就是代理模式的一个应用,下面看一个简单的例子,定义一个Person接口,里面有一个giveTask抽象方法,然后定义一个Person类,对giveTask方法进行实现
java中的原生的代理接口InvocationHandler,此接口中有一个invoke方法,用于获取代理对象,代理方法,代理方法的参数! 然后我们进行测试,在Main方法中,
Person persson = (Person)Proxy.newProxyInstance(Person.class.getClassLoader(),new Class<?>[]{Person.class},studentInvocationHandler);
java的原生方法中只能代理接口,无法代理类!
我们使用这个参数观察jvm生成的Proxy对象,来观察他是如何工作的?
然后观察编译后生成后的对象,会发现生成了代理对象
Spring 中AOP的使用
看一下bean如何被包装为proxy
上面说了原生的java代理只能代理接口,针对没有接口的类,spring采用cglib,进行代理,我们看一下他是如何选择使用哪一代理类的!
getProxy()方法
invoke()方法
Spring动态创建bean
我们一般使用spring的时候,都是先声明好自己要用的bean,在需要的地方注入到,如下图
接下来提供另外一种思路,能够在运行时动态的注册bean
1、在启动动时读取配置,打入spring容器中 bean的生成,先进行beanDefinition的生成,通过beanDefinition生成Spring Bean
我们在postProcessBeanFactory这一步骤,进行我们的扩展,这里就是我们的扩展点将BeanDefinition打入容器中
通过BeanFactoryPostProcessor,这个扩展点,将BeanDefinition打入容器,这样就是一个正常的bean,可以享受spring的各种增强
Note:但是要注意这个时候其他的bean都还没有生成,所有的注入都是无效的
2、启动完成后,需要新增bean的 如果不需要spring的各项增强,仅仅只是定义一个单例bean beanFactory.registerSingleton("personManager3", personManager);
注解背后的底层实现
注解Annotation 作为特定的标记,用于告诉编译器一些信息 编译时动态处理,如动态生成代码(lombok) 运行时动态处理,作为额外信息的载体,如获取注解信息
注解本身不具有任何的功能,可以看做是程式的注释,假如没有解析他的代码是没有作用的
注解看起来跟一般的类非常的不同,可以通过里面的方法拿到标记的属性值,下面讲解一下他的工作原理
1、通过键值对的形式为注解属性赋值
2、编译器检查注解的使用范围,将注解信息写入元素属性表
3、运行时JVM将RUMTIME的所有注解属性取出并最终存入Map里
3、jvm创建AnnotationInvocationHandler实例并传入前面的map
4、JVM使用JDK动态代理为注解生成代理类,并初始化处理器
5、调用invoke方法,通过传入方法名返回注解对应的属性