一、AOP以JDK版实现
1.定义接口
package cn.hq.service;
public interface StudentService {
public String getUser() throws Exception;
public void save(String name) throws Exception;
public void update(String name) throws Exception;
}
2.接口实现
package cn.hq.service.impl;
import cn.hq.service.StudentService;
public class StudentServiceImpl implements StudentService {
private String user;
public String getUser() {
return user;
}
public StudentServiceImpl() {}
public StudentServiceImpl(String user) {
this.user = user;
}
public void save(String name) throws Exception {
System.out.println("save()==>" + name);
}
public void update(String name) {
System.err.println("update()==>" + name);
}
}
3.代理类工厂
package cn.hq.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.hq.service.StudentService;
public class JDKProxyFactory implements InvocationHandler{
private Object targetObject;
public JDKProxyFactory() {}
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(
this.targetObject.getClass().getClassLoader(), //类加载器
this.targetObject.getClass().getInterfaces(), //类中的所有接口
this); //当前对象 此处较为重要 通过此处回调 invoke函数
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { //--环绕通知
StudentService bean = (StudentService)this.targetObject;
Object result = null;
if(bean.getUser() != null) {
//---spring中的advice()---前置通知
try {
result = method.invoke(targetObject, args);
//afterAdivice()-----后置通知
} catch (Exception e) {
// exceptionAdivce()---异常通知
}finally {
//finallyAdive()----后置通知
}
}
return result;
}
}
4.测试
@Test
public void proxyTest() {
JDKProxyFactory factory =new JDKProxyFactory();
StudentService studentService = (StudentService) factory.createProxyInstance(new StudentServiceImpl("zzz"));
try {
if(studentService.getUser() != null && !"".equals(studentService.getUser())) {
studentService.save("dddd");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
二、AOP以CGLib实现
1.定义方法类
package cn.hq.service.impl;
public class TeacherServiceBean {
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public void save() throws Exception{
System.out.println(this.getClass().getName() + "====>save()");
}
}
2.代理类工厂
package cn.hq.aop;
import java.lang.reflect.Method;
import cn.hq.service.impl.TeacherServiceBean;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibProxyFactory implements MethodInterceptor{
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass()); //非Final
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable { //--环绕通知
TeacherServiceBean teacherServiceBean = (TeacherServiceBean)this.targetObject;
Object result = null;
if(teacherServiceBean.getUser() != null) {
//---spring中的advice()---前置通知
try {
result = methodProxy.invoke(targetObject, args);
//afterAdivice()-----后置通知
} catch (Exception e) {
// exceptionAdivce()---异常通知
}finally {
//finallyAdive()----后置通知
}
}
return result;
}
}
3.测试
@Test
public void cglibProxyTest() {
CGlibProxyFactory factory =new CGlibProxyFactory();
TeacherServiceBean bean = (TeacherServiceBean) factory.createProxyInstance(new TeacherServiceBean());
try {
bean.save();
} catch (Exception e) {
e.printStackTrace();
}finally{
}
}
4.注,CGLib实现需要添加jar包
asm-3.3.1.jar
cglib-2.2.2.jar
三、两者的区别
JDK版的代理实现,方法类必须要有接口实现。。采用的动态代理的方式
CGLib不需要实现接口。。具体是使用继承的重载的方式