这里介绍两种方式实现
1.jdk动态代理(我这里只介绍环绕通知的写法,其他几种通知的写法大同小异)
1>首先建一个类叫JDKDynamicProxy,当然我写的是一个内部类实现动态代理,也可以实现InvocationHandler
public class JDKDynamicProxy {
public Object getProxyObject(final Object targetObject,final Object aspectObject){
Object proxyObj=Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ProceedingJoinPoint pjp=new ProceedingJoinPoint();
pjp.setTargetObject(targetObject);
pjp.setSignation(method);
pjp.setArgs(args);
Method[] methods = aspectObject.getClass().getDeclaredMethods();
Object result=null;
for (Method aspectMethod : methods) {
if("around".equals(aspectMethod.getName())){
result=aspectMethod.invoke(aspectObject, pjp);
}
}
return result;
}
});
return proxyObj;
}
}
这里需要注意:jdk实现动态代理传进来的目标对象必须要有接口。
2>新建一个类ProceedingJoinPoint
public class ProceedingJoinPoint {
private Method signation;
private Object targetObject;
private Object[] args;
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public ProceedingJoinPoint() {
super();
}
public ProceedingJoinPoint(Object targetObject) {
this.targetObject = targetObject;
}
public Method getSignation() {
return signation;
}
public void setSignation(Method signation) {
this.signation = signation;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public Object proceed(){
try {
Object returnValue = signation.invoke(targetObject, args);
return returnValue;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}
}
}
这样就可以实现插入切面。例如要插入一个事务,可以在事物类中写around方法
public class Transaction {
public Object around(ProceedingJoinPoint pjp){
System.out.println("开启事务");
pjp.proceed();
System.out.println("关闭事务");
return pjp.getTargetObject();
}
}
在测试代码中将目标对象和事务对象分别传到JDKDynamicProxy的实例化对象getProxyObject方法中
2.CGLIB动态代理实现
1>首先实现一个类CGLIBDynamicProxy,
public class CGLIBDynamicProxy {
public static Object getProxyObject(Object targetObject,Object aspectObject){
Object returnValue=null;
Enhancer hancer=new Enhancer();
hancer.setSuperclass(UserServiceImpl.class);
hancer.setCallback(new ProceedingJoinPoint(targetObject,aspectObject));
returnValue=hancer.create();
return returnValue;
}
}
2>新建一个类ProceedingJoinPoint
public class ProceedingJoinPoint implements MethodInterceptor{
private Method signation;
private Object targetObject;
private Object aspectObject;
private Object[] args;
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public ProceedingJoinPoint() {
super();
}
public ProceedingJoinPoint(Object targetObject,Object aspectObject) {
this.targetObject = targetObject;
this.aspectObject=aspectObject;
}
public Method getSignation() {
return signation;
}
public void setSignation(Method signation) {
this.signation = signation;
}
public Object getTargetObject() {
return targetObject;
}
@Override
public Object intercept(Object proxy,
Method method,
Object[] args, MethodProxy methodProxy) throws Throwable {
this.setSignation(method);
this.setArgs(args);
Method[] methods = aspectObject.getClass().getDeclaredMethods();
Object result=null;
for (Method aspectMethod : methods) {
if("around".equals(aspectMethod.getName())){
result=aspectMethod.invoke(aspectObject, this);
}
}
return result;
}
public Object proceed(){
try {
Object returnValue = signation.invoke(targetObject, args);
return returnValue;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}
}
}
注意:使用CGLIB动态代理,目标类不能使最终类。