目录
一、自己的理解(可能有误)
(一)描述
概述:就是在一个运行过程中,或者在某一个节点上面加入另外的实现功能。我浅显的理解是这样。
实现:
1、首先定义接口类。
2、实现接口类。
3、创建切面类。第一个方法:在切面类里面创建方法,这个方法用于创建被代理的对象。第二个方法:方法调度。是继承自InvocationHandler接口的方法invoke()方法。实现方法调度。
4、创建测试类。实例化代理类对象。实例化目标对象。把实例化后的目标对象传入代理类。代理类里面的方法管理这些方法的执行。
二、JDK动态代理
(一)步骤
1、创建接口类。
2、创建接口实现类。
3、创建切面类。
4、创建代理类。
5、创建测试类。
(二)例子
1、创建接口类,名为:UserDao
package com.stx.chapter03.JDK;
public interface UserDao {
public void addUser();
public void deleteUser();
}
2、创建接口实现类,名为:UserDaoImpl
package com.stx.chapter03.JDK;
/**
* 目标类。
* */
public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
3、创建切面类,名为:MyAspect
package com.stx.chapter03.aspect;
/**
* 切面类:可以存在多个通知Advice(),即增强方法。
* */
public class MyAspect {
public void check_Permissions(){
System.out.println("模拟检查权限!");
}
public void log(){
System.out.println("模拟记录日志!");
}
}
4、创建代理类,名为:JdkProxy
package com.stx.chapter03.JDK;
import com.stx.chapter03.aspect.MyAspect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Jok代理类
* */
public class JdkProxy implements InvocationHandler {
// 申明目标类接口。
private UserDao userDao;
// 创建代理方法。
public Object createProxy(UserDao userDao){
this.userDao=userDao;
// 1、类加载器。
ClassLoader classLoader = JdkProxy.class.getClassLoader();
// 2、被代理对象实现的所有接口。
Class[] clazz = userDao.getClass().getInterfaces();
// 3、使用代理类,进行增强,返回的是代理后的对象。
return Proxy.newProxyInstance(classLoader,clazz,this);
}
/*
* 所有动态代理类的方法调用,都会交由Invoke()方法处理。
* proxy被代理后的对象。
*
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 申明切面。
MyAspect myAspect = new MyAspect();
// 前增强
myAspect.check_Permissions();
// 在目标类上调用方法,并传入参数
Object obj = method.invoke(userDao,args);
// 后增强
myAspect.log();
return obj;
}
}
5、创建测试类,名为:JdkTest
package com.stx.chapter03.aspect;
/**
* 切面类:可以存在多个通知Advice(),即增强方法。
* */
public class MyAspect {
public void check_Permissions(){
System.out.println("模拟检查权限!");
}
public void log(){
System.out.println("模拟记录日志!");
}
}
6、目录结构
三、CGLIB代理
(一)、概述
、这种方式不用实现接口,直接创建实现类的动态代理。
(二)、步骤
1、创建实体类。
2、创建代理类。
3、创建测试类。
(三)、例子
1、创建实体类,名为:UserDao
package com.stx.chapter03.cglib;
public class UserDao {
public void addUser(){
System.out.println("添加用户!");
}
public void deleteUser(){
System.out.println("删除用户!");
}
}
2、创建代理类,名为:CglibProxy
package com.stx.chapter03.cglib;
import com.stx.chapter03.jdkproxy.aspect.MyAspect;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 代理类
* */
public class CglibProxy implements MethodInterceptor {
/*
* 代理方法
* */
public Object createProxy(Object target){
// 创建一个动态类对象
Enhancer enhancer = new Enhancer();
// 确定需要增强的类,设置其父类。
enhancer.setSuperclass(target.getClass());
// 添加回调函数
enhancer.setCallback(this);
// 返回创建的代理类
return enhancer.create();
}
/*
* proxy CGlib 根据指定父类生成的代理对象。
* method 拦截的方法。
* args 拦截方法的参数数组。
* methodProxy 方法的代理对象,用于执行父类方法。
* */
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 创建切面类。
MyAspect myAspect = new MyAspect();
// 前增强。
myAspect.check_Permissions();
// 目标方法执行。
Object object = methodProxy.invokeSuper(o,objects);
// 后增强。
myAspect.log();
return object;
}
}
3、创建测试类,名为:CglibTest
package com.stx.chapter03.cglib;
public class CglibTest {
public static void main(String[] args) {
// 创建代理对象
CglibProxy cglibProxy = new CglibProxy();
// 创建目标对象
UserDao userDao = new UserDao();
// 获取增强后的目标对象
UserDao userDao1 = (UserDao)cglibProxy.createProxy(userDao);
// 执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}