什么是AOP?
AOP实际是设计模式的延续,设计模式孜孜不倦所追求的就是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
Aspect是程序设计一个新的中心,AOP并不取代OOP,两者各有各的角色,将职责各自分配给Object与Aspect,会使得程序中各个组件的角色更为清楚。
代理机制分为静态代理和动态代理
本文着重介绍动态代理,静态代理这里不细说(但需要注意:代理对象的一个接口只服务于一种类的对象,而且如果要代理的方法很多,我们势必要为每个方法进行代理,静态代理在程序规模稍大时就必定无法胜任。)
JDK动态代理
Java在JDK1.3之后加入协助开发动态代理功能的类,我们不必为特定对象与方法写特定的代理,使用动态代理,可以使得一个handler服务于各个对象,一个handler必须实现java.lang.reflect.InvocationHandler。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK的动态里要求,被代理对象必须实现接口
* @author boyas
*/
public class MyHandler implements InvocationHandler {
//被代理对象
private Object targetObject;
//传入被代理对象,返回一个代理对象
public Object createProxy(Object targetObject){
//把需要被代理的对象传入到本对象中
this.targetObject=targetObject;
//通过被代理对象生成它的代理对象,并且同MyHandler绑定在一起
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("打开会话连接");
Object result=method.invoke(targetObject,args);
System.out.println("有事务提交事务,关流");
return result;
}
}
InvocationHandler的invoke()方法会传入代理对象的方法名称与参数,实际上要执行的方法交由method.invoke(),并在其前后加上记录动作,method.invoke()返回的对象是实际方法执行过后的回传结果。
JDK动态代理必须有接口
public interface UserService {
void insertUser();
}
JDK的动态里要求,被代理对象必须实现接口
public class UserServiceImpl implements UserService {
@Override
public void insertUser() {
System.out.println("执行添加用户方法");
}
}
创建代理对象
/**
*传入一个被代理对象,返回一个代理对象
*调用被代理对象中的任何一个方法时,都会使用代理在其前后加上一些动作
*/
public class MainTest {
public static void main(String[] args) {
//创建代理对象
MyHandler myHandler = new MyHandler();
UserService userService=(UserService)myHandler.createProxy(new UserServiceImpl());
userService.insertUser();
}
}
运行
CGLib动态代理
当代理对象没有实现接口,我们就可以使用CGLIB生成代理,如果采用eclipse可以导入cglib-nodep-2.1_3.jar,如果是IDEA导入cglib依赖就行。
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* cglib动态代理,被代理对象可以没有实现接口
* 传入被代理对象,返回代理对象,代理对象是被代理对象的子类
*/
public class CGLIBHandler implements MethodInterceptor {
//被代理对象
private Object targetObject;
//传入一个代理对象,返回一个代理对象
public Object createProxy(Object targetObject) {
this.targetObject = targetObject;
//设置代理对象
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("打开");
Object invoke=arg1.invoke(targetObject,arg2);
System.out.println("关闭");
return invoke;
}//CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
}
没有实现接口
public class UserServiceImpl {
public void insertUser() {
System.out.println("执行添加用户方法");
}
}
测试
public class MainTest {
public static void main(String[] args) {
CGLIBHandler cglibHandler=new CGLIBHandler();
UserServiceImpl userServiceImpl=(UserServiceImpl)cglibHandler.createProxy(new UserServiceImpl());
userServiceImpl.insertUser();
}
}
运行