您的位置:首页 > 编程语言 > Java开发

模拟spring,Aop(JDK与CGLib两种方式实现)

2017-10-12 13:25 741 查看
一、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() {
ret
4000
urn 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不需要实现接口。。具体是使用继承的重载的方式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: