代理模式: 调用端 》 代理端 》 目标端 (实现类)
通过代理控制对象的访问, 可以在调用目标对象的前后增加操作, 比如日志, AOP.
代理模式分为 :
1: 静态代理: 需要根据需要创建代理类
2: 动态代理: 只需要实现接口就可以代理所有访问。
2.1: jdk动态代理: 通过反射实现代理接口的匿名类。
2.2: cglib动态代理: 通过加载目标对象的类class文件, 修改其字节码生成子类来实现。
静态代理代码:
interface Tests {
void create();
}
class TestImpl implements Tests {
@Override
public void create() {
System.out.println(".....我是实现类。。。。");
}
}
class TestProxy implements Tests {
private TestImpl testImpl;
public TestProxy(TestImpl testImpl)
{
this.testImpl = testImpl;
}
@Override
public void create() {
System.out.println("代理前。。。。");
testImpl.create();
System.out.println("代理后。。。。");
}
}
public class Test{
public static void main(String[] args) {
new TestProxy(new TestImpl()).create();
}
}
运行结果:
动态代理代码:
jdk动态代理:
interface Tests {
void create();
}
class TestImpl implements Tests {
@Override
public void create() {
System.out.println(".....我是实现类。。。。");
}
}
//jdk动态代理
class JdkProxys implements InvocationHandler{
private TestImpl testImpl;
public JdkProxys(TestImpl testImpl)
{
this.testImpl = testImpl;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理前。。。。");
Object invoke = method.invoke(testImpl, args);
System.out.println("代理后。。。。");
return invoke;
}
}
public class Test{
public static void main(String[] args) {
JdkProxys jdkProxys = new JdkProxys(new TestImpl());
Tests tests = (Tests) Proxy.newProxyInstance(TestImpl.class.getClassLoader(), TestImpl.class.getInterfaces(), jdkProxys);
tests.create();
}
}
cglib 动态代理: 引入:这两个jar包:
interface Tests {
void create();
}
class TestImpl implements Tests {
@Override
public void create() {
System.out.println(".....我是实现类。。。。");
}
}
//cglib代理
class CglibProxys implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
System.out.println("代理前。。。。");
Object invokeSuper = methodProxy.invokeSuper(obj,params);
System.out.println("代理后。。。。");
return invokeSuper;
}
}
public class Test{
public static void main(String[] args) {
CglibProxys cglibProxys = new CglibProxys();
Enhancer enhancer = new Enhancer();
enhancer.setCallback(cglibProxys);
enhancer.setSuperclass(TestImpl.class);
Tests test = (Tests) enhancer.create();
test.create();
}
}
jdk动态代理与 cglib动态代理的区别:
jdk动态代理: 通过反射实现代理接口创建匿名类实现。
cglib动态代理:通过加载目标对象的class文件,修改字节码实现。
1: 目标对象实现了接口, 默认采用 jdk动态代理实现aop;
2: 目标对象实现了接口, 可以强制转为cglib动态代理实现aop;
3: 目标对象没有实现接口, 必须采用cglib动态代理。
spring 会在 jdk 与 cglib 之间自动切换。