JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。要求被代理类必须实现一个接口 . 如下案例
接口
public interface TargetInterface {
public void say();
}
被代理类
public class Target implements TargetInterface{
@Override
public void say() {
System.out.println("方法被执行了");
}
}
代理测试类
public class JDK_Proxy {
public static void main(String[] args) {
Target target = new Target();
//jdk动态代理
TargetInterface proxyInstance = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args1) -> {
System.out.println("方法执行前");
Object invoke = method.invoke(target, args);
System.out.println("方法执行后");
return invoke;
}
);
proxyInstance.say();
}
}
输出结果
与JDK动态代理不同,cglib的目标类可以不实现接口
被代理类
public class CGLB_Target {
public void say() {
System.out.println("方法被执行了");
}
}
代理测试类
/**
* @author sz
* @DATE 2022/4/6 18:44
*/
public class CGLB_Proxy {
public static void main(String[] args) {
//创建一个增强器
Enhancer enhancer = new Enhancer();
//设置父类 也就是被代理的类
enhancer.setSuperclass(CGLB_Target.class);
//设置代理逻辑
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
/**
* @param o 代理类
* @param method 目标方法
* @param objects 方法参数
* @param methodProxy 代理方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglb增强_方法执行前");
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("cglb增强_方法执行后");
return result;
}
}});
//创建代理类
CGLB_Target cglb_target = (CGLB_Target) enhancer.create();
cglb_target.say();
}
}
输出结果
被代理类
public class CGLB_Target {
public void say() {
System.out.println("方法被执行了");
}
}
前置通知
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("beanfactory ---> 方法执行前");
}
}
返回后通知
public class MyAfterReturnAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("beanfactory --->"+method.getName()+" 方法 返回值为 "+returnValue);
}
}
异常通知
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
{
System.out.println("beanfactory ---> 方法执行抛出异常"+ex.getMessage());
}
}
创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new CGLB_Target());
//前置通知
proxyFactory.addAdvice(new MyBeforeAdvice());
//返回后通知
proxyFactory.addAdvice(new MyAfterReturnAdvice());
//异常后通知
proxyFactory.addAdvice(new MyThrowsAdvice());
CGLB_Target proxy = (CGLB_Target) proxyFactory.getProxy();
proxy.say();
执行结果
在SpringAOP中一个切面类由切入点和通知组成 同样的 Advisor 也由切入点和通知组成
如果想对一个类中的say方法代理
//创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
//设置代理类
proxyFactory.setTarget(new CGLB_Target());
//创建advisore
proxyFactory.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class> targetClass) {
if ("say".equals(method.getName())){
return true;
}
return false;
}
};
}
@Override
public Advice getAdvice() {
return new MyAfterReturnAdvice();
}
@Override
public boolean isPerInstance() {
return false;
}
});
//创建代理类
CGLB_Target proxy = (CGLB_Target) proxyFactory.getProxy();
proxy.say();