1. Demonstration of two dynamic proxy methods
1.1 JDK dynamic proxy
The dynamic proxy of JDK is the process of dynamically generating the class file of the proxy class according to the proxy interface during the running process of the program, and loading and running. Requires that the proxied class must implement an interface. The following case
interface
public interface TargetInterface {
public void say();
}
proxied class
public class Target implements TargetInterface{
@Override
public void say() {
System.out.println("方法被执行了");
}
}
Proxy test class
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();
}
}
output result
1.2 CGLB dynamic proxy
Unlike the JDK dynamic proxy, the target class of cglib can not implement the interface
proxied class
public class CGLB_Target {
public void say() {
System.out.println("方法被执行了");
}
}
Proxy test class
/**
* @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();
}
}
output result
2. ProxyFactory encapsulated by Spring
1. Simple use case of proxy factory ProxyFactory
proxied class
public class CGLB_Target {
public void say() {
System.out.println("方法被执行了");
}
}
advance notice
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("beanfactory ---> 方法执行前");
}
}
Notify when you return
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);
}
}
exception notification
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
{
System.out.println("beanfactory ---> 方法执行抛出异常"+ex.getMessage());
}
}
Create a proxy factory
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();
Results of the
2. Notification interface
- `MethodBeforeAdvice pre-advice
- `AfterReturningAdvice return notification
- `ThrowsAdvice notification after exception
3.Advisor
In Spring AOP, an aspect class consists of pointcuts and advice, and the same Advisor consists of pointcuts and advice.
If you want to proxy the say method in a class
//创建代理工厂
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();