学习spring过程中学习了它的核心思想AOP,也就是面向切面编程,而AOP的就是通过动态代理实现,动态代理有基于JDK模式的实现以及cglib继承的实现。
1:什么是代理?作用?
代理为其他对象提供一种代理以控制对这个对象的访问。说白了就是,在一些情况下客户不想或者不能直接引用一个对象,而代理对象可以在客户和目标对象之间起到中介作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务。它显得更专业,相对于原来的实现类来说的话。
2:实例:
我们模拟一个场景,在一个类中要加入权限认证的功能,如果是传统的做法,可以在业务源代码中添加代码,但这样对系统有侵入性,不好。通过动态代理就可以很好解决了。
3:代理模式涉及的专业名词:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻 辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
4:代理模式的优点
(1).职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
(3).高扩展性
5:实例测试
a:先定义一个产品的接口:
package com.yc.biz;
public interface ProductBiz {
public void addProduct();
}
实现类:
package com.yc.biz.impl;
import com.yc.biz.ProductBiz;
//真实主题
public class ProductBizImpl implements ProductBiz{
@Override
public void addProduct() {
System.out.println("********************");
System.out.println("添加产品");
System.out.println("********************");
}
}
jdk动态代理的实现:
package com.yc.advice;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//这个类是一个切面类,完成的是向目标类的目标方法加入功能(增强)
public class RightAdvice implements InvocationHandler{
//代理模式最核心:代理模式中一定要有目标类的引用
private Object targetObject; //注意:这个就是目标类的引用
/* public RightAdvice( Object targetObject){
this.targetObject=targetObject;
}*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName=method.getName();
if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("aupdate")){
//在invoke中加入您要增强的代码
check();
}
//调用目标类的对应的发放那个方法
Object returnvalue=method.invoke(targetObject, args);
return returnvalue;
}
//创建一个方法来完成创建代理对象
//代理模式最核心:代理模式中一定要有目标类的引用
public Object createInstance(Object targetObject){
this.targetObject=targetObject;
//生成一个代理对象
//生成一个代理对象,这个代理对象是根据目标类的接口生成的
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
//在客户端,我们调用ceateInstance()得到一个代理对象,在调用这个代理对象的方法,-->它就会自动的回调(因为this)--》invoke
}
public void check(){
System.out.println("$$$$$$$$$$$$$$$$$$$");
System.out.println("权限检查");
System.out.println("$$$$$$$$$$$$$$$$$$$");
}
}