概念:
动态代理是设计模式中比较常见的代理模式,大家见得最多的应该是spring aop的动态代理。动态代理是指为对象创建一个代理对象,通过这个代理对象对被代理对象的功能进行增强。动态代理是属于结构型设计模式。
动态代理分为两类:
- 静态代理
- 动态代理(有分为JDK代理、cglib代理)
静态代理
类图:?
代理对象和目标对象要实现相同的接口,然后通过调用相同的方法来调用目标对象的方法。
新建接口:
public interface ITeacherDao {
public void teach();
}
创建接口实现类:
public class TeacherDao implements ITeacherDao{
@Override
public void teach() {
System.out.println("正在授课。。。。。。");
}
}
创建代理类:
public class ITeacherDaoProxy implements ITeacherDao{
private ITeacherDao target;
public ITeacherDaoProxy(ITeacherDao target){
this.target=target;
}
@Override
public void teach() {
System.out.println("教授课程之前。。。。。");
target.teach();
System.out.println("教授课程之后。。。。。");
}
}
新建测试类:
public class client {
public static void main(String[] args) {
ITeacherDao iTeacherDao=new TeacherDao();
ITeacherDaoProxy iTeacherDaoProxy = new ITeacherDaoProxy(iTeacherDao);
iTeacherDaoProxy.teach();
}
}
动态代理
JDK代理(有接口)
代理对象不需要实现接口,但是目标对象需要实现接口,否则不能使用动态代理。
创建代理对象是通过JDK的api,动态的创建代理对象。
JDK通过反射包下的proxy类的newProxyInstance方法动态创建代理对象。
实现
类图 :
新建接口:
public interface ITeacherDao {
public void teach();
}
?创建接口实现类:
public class TeacherDao implements ITeacherDao{
@Override
public void teach() {
System.out.println("正在教授。。。。。。");
}
}
创建代理类:
public class TeacherDaoProxy {
private ITeacherDao target;
public TeacherDaoProxy(ITeacherDao target){
this.target=target;
}
public Object getProxyInstance(){
/**
* Object newProxyInstance(ClassLoader loader, 目标类的加载器
* Class<?>[] interfaces, 目标类的接口
* InvocationHandler h) 事件处理,调用目标方法时,会触发事件处理方法
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始。。。。");
//反射机制调用目标对象的方法
Object returnVal=method.invoke(target,args);
System.out.println("JDK代理结束。。。。");
return returnVal;
}
}
);
}
}
创建测试类:
public class client {
public static void main(String[] args) {
TeacherDao teacherDao=new TeacherDao();
ITeacherDao proxyInstance = (ITeacherDao) new TeacherDaoProxy(teacherDao).getProxyInstance();
proxyInstance.teach();
}
}
Cglib代理(没有接口)
静态代理和JDK代理都要求目标对象实现一个接口,但有的时候目标对象只有一个单独的对象,并没有实现任何接口,这个时候可使用目标对象的子类来实现代理,这就是cglib动态代理。
实现
类图:
1、导入依赖(cglib代理需要依赖外部的jar包)。
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2、创建目标类。
public class TeacherDao {
public void teach(){
System.out.println("正在教授。。。。。。");
}
}
3、创建代理类,实现MethodInterceptor接口。
public class proxyFactory implements MethodInterceptor {
private Object target;
public proxyFactory(Object target){
this.target=target;
}
public Object getProxyInstance(){
//1、创建工具类
Enhancer enhancer = new Enhancer();
//2、设置父类
enhancer.setSuperclass(target.getClass());
//3、设置回调函数
enhancer.setCallback(this);
//4、创建子类对象,即代理对象
return enhancer.create();
}
//当代理对象调用目标方法时,触发该事件方法
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib代理模式开始。。。。。。");
Object returnVal = method.invoke(target, args);
System.out.println("cglib代理模式结束。。。。。。");
return returnVal;
}
}
4、创建测试类。
public class client {
public static void main(String[] args) {
TeacherDao teacherDao=new TeacherDao();
TeacherDao proxyFactory = (TeacherDao) new proxyFactory(teacherDao).getProxyInstance();
proxyFactory.teach();
}
}
|