动态代理
参考资料
设计模式之禅: https://item.jd.com/10095020247922.html
静态代理
SysdictService
package com.laolang.bzrj.mybatis.proxy.staticproxy;
public interface SysdictService {
String selectName();
}
SysdictServiceImpl
package com.laolang.bzrj.mybatis.proxy.staticproxy;
public class SysdictServiceImpl implements SysdictService{
@Override
public String selectName() {
System.out.println("select name");
return "system_setting";
}
}
SysdictServiceProxy
package com.laolang.bzrj.mybatis.proxy.staticproxy;
public class SysdictServiceProxy implements SysdictService {
private final SysdictService target;
public SysdictServiceProxy(SysdictService target) {
this.target = target;
}
@Override
public String selectName() {
System.out.println("pre action");
String result = target.selectName();
System.out.println("post action");
return result;
}
}
test
package com.laolang.bzrj.mybatis.proxy.staticproxy;
import org.testng.annotations.Test;
public class StaticProxyTest {
@Test
public void staticTest() {
SysdictService target = new SysdictServiceImpl();
SysdictServiceProxy proxy = new SysdictServiceProxy(target);
String ret = proxy.selectName();
System.out.println("ret:" + ret);
}
}
输出
pre action
select name
post action
ret:system_setting
优缺点
优点: 在不修改目标对象的功能前提下,能通过代理对象对目标功能扩展
缺点: 需要与被代理对象实现相同的接口,需要同事维护被代理对象和代理对象
jdk 代理
SysdictServiceProxyFactory
package com.laolang.bzrj.mybatis.proxy.jdkproxy;
import java.lang.reflect.Proxy;
public class SysdictServiceProxyFactory {
private final Object target;
public SysdictServiceProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> {
System.out.println("pre action");
Object ret = method.invoke(target, args);
System.out.println("post action");
return ret;
});
}
}
测试
SysdictService
与SysdictServiceImpl
和上面的一样
package com.laolang.bzrj.mybatis.proxy.jdkproxy;
import org.testng.annotations.Test;
public class JdkProxyTest {
@Test
public void jdkTest() {
SysdictService target = new SysdictServiceImpl();
SysdictServiceProxyFactory proxyFactory = new SysdictServiceProxyFactory(target);
SysdictService proxy = (SysdictService) proxyFactory.getProxyInstance();
String ret = proxy.selectName();
System.out.println("ret:" + ret);
}
}
cglib
pom
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
SysdictServiceImpl
package com.laolang.bzrj.mybatis.proxy.cglibproxy;
public class SysdictServiceImpl {
public String selectName() {
System.out.println("select name");
return "system_setting";
}
}
SysdictServiceProxyFactory
package com.laolang.bzrj.mybatis.proxy.cglibproxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class SysdictServiceProxyFactory implements MethodInterceptor {
private final Object target;
public SysdictServiceProxyFactory(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("pre action");
Object ret = method.invoke(target, args);
System.out.println("post action");
return ret;
}
}
test
package com.laolang.bzrj.mybatis.proxy.cglibproxy;
import org.testng.annotations.Test;
public class CglibProxyTest {
@Test
public void cgligTest(){
SysdictServiceImpl target = new SysdictServiceImpl();
SysdictServiceProxyFactory proxyFactory = new SysdictServiceProxyFactory(target);
SysdictServiceImpl proxy = (SysdictServiceImpl) proxyFactory.getProxyInstance();
String ret = proxy.selectName();
System.out.println("ret:" + ret);
}
}
注意
cglib
不能代理final
修饰的class
cglib
不能拦截final
或static
修饰的方法