一、什么是Spring的AOP(面向切面编程)采取横向机制即动态代理的方式创建一个代理对象。
1、动态代理即为生成一个和原来类方法一摸一样的类,在方法内调用原来类的方法,在方法前后可以加入额外的功能代码。
二、目前流行的AOP框架有两个,Spring的AOP和AspectJ
三、AOP的实现,jdk的动态代理,CGLIB的动态代理。
1、基于jdk的动态代理,用到java.lang.reflectt.Proxy类
UserService userService=new UserServiceImpl();
UserService userService1 = (UserService)Proxy.newProxyInstance(BeanFactor.class.getClassLoader(),userService.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy,Method method,Object[]args)throws Throwable {
System.out.println("before");
//userService原来类的执行方法
Object obj =method.invoke(userService,args);
System.out.println("after");
return obj;
}
});
newProxyInstance()后的参数第一个放类加载器,第二个放原本类的接口,第三个给一个实现InvocationHandler接口的类。
2、基于CGLIB的动态代理,用到cglib.proxy.Enhancer类
Enhancer enhancer=new Enhancer();
UserService userService=new UserServiceImpl();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o,Method method,Object[]objects,MethodProxy methodProxy)throws Throwable {
System.out.println("before");
Object obj =method.invoke(userService,objects);
System.out.println("after");
return obj;
}
});
Object obj =enhancer.create();
第一setSuperclass设置原来类的父类,第二setCallback调回原来的方法调用,参数给个实现MethodInterceptor接口的类,该接口为cglib.proxy.MethodInterceptor包的接口。
JDK动态代理相比较CGLIB动态代理有一定局促行,前者必须要实现接口才行,而CGLIB不需要实现接口,它采用反射对目标类生成子类,并对子类进行增强。
四、Spring框架中集成了CGLIB所需要的jar包。
1、基于xml方式动态代理
<bean id="is" class="com.qianfeng.IServiceImpl"></bean>
<bean id="as" class="com.qianfeng.service.Aspect2" ></bean>
<bean id="bf" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.qianfeng.IService"/>
<property name="target" ref="is"/>
<property name="interceptorNames" value="as"/>
<property name="optimize" value="true"/>
</bean>
public class Aspect implements MethodInterceptor {
public void before(){
System.out.println("---before---");
}
public void after(){
System.out.println("---after---");
}
@Override
public Object invoke(MethodInvocation invocation)throws Throwable {
before();
Object obj =invocation.proceed();
after();
return obj;
}
}
这里用到的是org.springframework.aop.framework.ProxyFactoryBean类,该类中设置4个属性,interfaces即为接口类或者父类,target即为目标代理的类,后面为ref属性,interceptorNames为写入的增强方法的类(该类需要实现MethodInterceptor接口)该接口为org.aopalliance.intercept包下。
五、ProxyBeanFactory、ApplicationContext和BeanFactory的区别
BeanFactory是顶级接口,是Spring的核心容器。它是管理bean的工厂,提供了完整的IoC(控制反转)服务支持,负责初始化各种的bean。
ProxyBeanFactory是BeanFactory的实现类,它是负责管理动态代理类的bean工厂,负责动态代理类的初始化。
ApplicationContext是BeanFactory的子接口,也被称为应用上下文,是Spring的另一个常用的核心容器。它不仅包含了BeanFactory的所有功能,还添加了国际化、资源访问、事件传播等方面的支持。(实现ApplicationContext的两种方式,ClassPathXmlApplicationContext、FileSystemXmlApplicationContext).