AOP(Aspect-Oriented Programming 面向切面编程)
aop(Aspect-Oriented Programming)也就是面向切面编程,作为面向对象编程的一种补充。aop从程序运行角度考虑程序的流程,提取业务处理过程的切面。
1,AOP中的概念
Aspect(切面): 是通知(Advice)和切入点(Pointcut)的结合,通知和切入点共同定义了关于切面的全部内容---何时、何地、做什么。
Advice(通知): 所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能,通知定义了切面的”何时”和”做什么”)
Pointcut(切入点): 所谓切入点是指我们要对那些joinpoint进行拦截的定义. 切入点就定义了”何地”. JoinPoint(连接点): 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点. Target(目标对象): 代理的目标对象 Weaving(织入): 是指把切面应用到目标对象来创建新的代理对象的过程.切面在指定的连接点织入到目标对象 Introduction(引入): 在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field. AOP代理:springAOP创建的代理对象。也可以说是对目标对象的加强。spring中的代理可以是jdk的动态代理,也可以是CGLIB代理。前者为实现接口的对象进行代理,后者是为了不实现接口的对象的代理。spring会根据具体的类是否有接口来以不同的方式处理代理过程。
2,spring中的两种代理(内部实现)
1,JDK的动态代理
JDK的动态代理主要的核心方法是:java.lang.reflect.Proxy类的 public static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h) throws IllegalArgumentException该方法。
其中参数 :
loader- 定义代理类的类加载器 、interfaces - 代理类要实现的接口列表、h- 指派方法调用的调用处理程序 。其中的InvocationHandler为java.lang.reflect下面的接口
返回:一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口
InvocationHandler接口只有一个方法:Object invoke(Object proxy, Method method, Object[] args) throws Throwable
代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
如下要在一个CustmerService的保存更新操作上面加上事务处理。
ICustomeService接口:
package com.xiaohui.proxy; public interface ICustomeService { void save(Customer c); void update(Customer c); }CustomerServiceImplCustomerServiceImpl类
package com.xiaohui.proxy; public class CustomerServiceImpl implements ICustomeService{ public void save(Customer customer) { System.out.println("CustomerServiceImpl......save..."+customer.getName()); } public void update(Customer c) { System.out.println("CustomerServiceImpl......update..."+c.getName()); } }MyInvocationHandlerFactoryMyInvocationHandlerFactory类
package com.xiaohui.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyInvocationHandlerFactory implements InvocationHandler { //目标对象 private Object target; /** *被代理的对象 * @param target * @return 代理对象 */ public Object getProxyInstance(Object target){ this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //proxy参数一般不用 //前置的处理逻辑程序 System.out.println("session.beginTranscation()"); //回调目标对象的方法 类似于filter中的chain.doFilter(request,response); Object obj = method.invoke(target, args); //后续的处理逻辑程序 System.out.println("session.getTranscation().commit()"); return obj; } }测试类:
@Test public void testProxy() throws Exception { ICustomeService service = new CustomerServiceImpl(); Customer customer = new Customer(); customer.setName("张珊"); MyInvocationHandlerFactory factory = new MyInvocationHandlerFactory(); ICustomeService serviceProxy =(ICustomeService) factory.getProxyInstance(service); serviceProxy.save(customer); System.out.println("-------------------------------"); serviceProxy