第一种:使用JDK中的Proxy技术实现AOP功能
public class JDKProxy implements InvocationHandler {
private Object targetObject;//代理的目标对象public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
/*
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.targetObject, args);//把方法调用委派给目标对象
}
}
当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
package cn.itm.service;
public interface PersonService {
public void save(String name);
public void update(String name,Integer personid);
public String getPersonName(Integer personid);
}package cn.itm.service.impl;
import cn.itm.service.PersonService;
/**
* 对这里面的所有方法 实施拦截,拦截到这个方式之后,我们判断,用户是否为 null,如果为null,就没有权限去调用这里面的方法。
* @author Administrator
*
*/
public class PersonServiceBean implements PersonService {
private String user = null;
public String getUser() {
return user;
}
public PersonServiceBean(){}
public PersonServiceBean(String user){
this.user = user;
}
@Override
public String getPersonName(Integer personid) {
System.out.println("我是 getPersonName()方法 ");
return "xxx";
}
@Override
public void save(String name) {
System.out.println("我是 save() 方法");
}
@Override
public void update(String name, Integer personid) {
System.out.println("我是 update() 方法");
}
}
package cn.itm.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.itm.service.impl.PersonServiceBean;
public class JDKProxyFactory implements InvocationHandler{
private Object targetObject;
/**
* 调用对象 会 被this 拦截到。拦截到后,他会执行invoke() 方法 也就是说:客户端调用代理对象业务方法的时候,代理对象就会执行 InvocationHandler 找 invoke()方法
*
* invoke方法就会 把 method的调用 委派给目标对象。
*
* @param targetObject
* @return
*/
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(
this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(),
this
);
}
/**
*
* @param proxy
* @param method : 代表被拦截到的方法,
* @param args : 代表方法的输入参数。
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean bean = (PersonServiceBean)this.targetObject;
Object result = null;
if(bean.getUser() != null){ // 代表如果有权限。
// 委派给目标对象。
result = method.invoke(targetObject, args);
}
return result;
}
}
package junit.test;
import org.junit.BeforeClass;
import org.junit.Test;
import cn.itm.aop.JDKProxyFactory;
import cn.itm.service.PersonService;
import cn.itm.service.impl.PersonServiceBean;
public class AOPTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test public void proxyTest(){
JDKProxyFactory factory = new JDKProxyFactory();
// 注意要使用接口 来饮用代理对象。
PersonService personService = (PersonService)factory.createProxyInstance(new PersonServiceBean("XXX"));
personService.save("999");
}
}
ok,成功。
第二种:使用cglib
public class CGLIBProxy implements MethodInterceptor {
private Object targetObject;//代理的目标对象
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();//该类用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
return methodProxy.invoke(this.targetObject, args);
}
}
CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
代码示例:
不用实现接口
package cn.itm.service.impl;
/**
* 对这里面的所有方法 实施拦截,拦截到这个方式之后,我们判断,用户是否为 null,如果为null,就没有权限去调用这里面的方法。
* @author Administrator
*
*/
public class PersonServiceBean{
private String user = null;
public String getUser() {
return user;
}
public PersonServiceBean(){}
public PersonServiceBean(String user){
this.user = user;
}
public String getPersonName(Integer personid) {
System.out.println("我是 getPersonName()方法 ");
return "xxx";
}
public void save(String name) {
System.out.println("我是 save() 方法");
}
public void update(String name, Integer personid) {
System.out.println("我是 update() 方法");
}
}
使用cglib实现:
package cn.itm.aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import cn.itm.service.impl.PersonServiceBean;
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());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return enhancer.create(); // 创建代理对象。
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean bean = (PersonServiceBean)this.targetObject;
Object result = null;
if(bean.getUser() != null){ // 代表如果有权限。
// 委派给目标对象。
result = methodProxy.invoke(targetObject, args);
}
return result;
}
}
测试类
package junit.test;
import org.junit.BeforeClass;
import org.junit.Test;
import cn.itm.aop.CGLIBProxyFactory;
import cn.itm.service.impl.PersonServiceBean;
public class AOPTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test public void cglibproxyTest(){
CGLIBProxyFactory factory = new CGLIBProxyFactory();
// 注意要使用接口 来饮用代理对象。
PersonServiceBean personServiceBean = (PersonServiceBean)factory.createProxyInstance(new PersonServiceBean(/*"XXX"*/));
personServiceBean.save("CGLIB----> 999");
}
}
本文详细介绍了如何使用Java平台提供的JDK Proxy技术和CGLIB库实现面向切面编程(AOP)。通过实例展示了如何为类方法添加前置、后置等通知逻辑,确保在执行业务方法前后执行特定的逻辑操作,从而提高代码的复用性和可维护性。
387

被折叠的 条评论
为什么被折叠?



