先来2个基础材料,一个接口,一个实现类。作为要提供对外服务的(用户需要访问的服务)。
写写,理解理解注释,main函数的效果,跑跑看看。不废话了。直接上干货,加油,各位。
public interface HelloService {
public void sayHello(String name);
}
public class HelloServiceImpl implements HelloService{
@Override
public void sayHello(String name) {
System.out.println("Hello "+name+",It's me !");
}
}
JDK 动态代理
/*
* @author <a>wang da wei</a>
* @description 代理类,提供真实对象的绑定和代理方式。代理类的要求是实现InvocationHandler接口的代理方法,当一个对象被绑定后,执行其方式的时候就会进入到代理方法里。
* 2021/11/28 1:38
* @version wang da wei 1.0.0
*/
package com.cosyit.corejava.core_aop.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理类,提供真实对象的绑定和代理方式。代理类的要求是实现InvocationHandler接口的代理方法,当一个对象被绑定后,执行其方式的时候就会进入到代理方法里。
*
* @author <a href="610495444@qq.com">wang da wei</a>
* 2021/11/28 1:38
* @version 1.0.0
*/
public class HelloServiceJDKProxy implements InvocationHandler {
/**
* 真实服务对象
*/
private Object target; //写完属性后,ctrl + alt + enter; 去上一行去写属性注释。
/**
* 绑定委托对象,并返回一个代理。
* @param target
* @return
*/
public Object bindInit(Object target){
this.target = target; //类似构造函数的玩法,给对象属性赋值。可是构造方法会在new 的时候,顺带执行。
//取得代理对象。
//第二个参数:JDK需要提供接口。JDK必须提供接口,才可以玩动态代理。所以为了克服这个缺陷,建议使用CGLIB开源框架。
System.out.println(this); //--- 参考 MainTest 函数玩法你会发现是HelloServiceProxy代理类它自己本类的对象,会来绑定执行这个函数。
Object o = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
return o;
}
/**
* 通过代理对象调用方法首先进入这个方法。
* @param proxy 代理对象
* @param method 被调用的方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("============ JDK 动态代理 ============");
Object result = null;
//反射方法调用前。
System.out.println("before hello...");
result= method.invoke(target,args);
System.out.println("after hello ...");
return result;
}
}
import com.cosyit.corejava.core_aop.HelloService;
import com.cosyit.corejava.core_aop.HelloServiceImpl;
/**
* @author <a href="610495444@qq.com">wang da wei</a>
* 2021/11/28 2:01
* @version 1.0.0
*/
public class JDKAOPMainTest {
public static void main(String[] args) {
HelloServiceJDKProxy helloHandler = new HelloServiceJDKProxy();
HelloService proxy = (HelloService) helloHandler.bindInit(new HelloServiceImpl());
proxy.sayHello("张三");
}
}
CGLIB aop联盟出品
/*
* @description cglib 需要实现MethodInterceptor
* 2021/11/28 2:22
* @version wang da wei 1.0.0
*/
package com.cosyit.corejava.core_aop.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* cglib 需要实现MethodInterceptor. (Mybatis 通常在延迟加载的时候,才会用到。)
* @author <a href="610495444@qq.com">wang da wei</a>
* 2021/11/28 2:22
* @version 1.0.0
*/
public class HelloServiceCglibProxy implements MethodInterceptor {
/**
* 真实的服务对象。外部调用把参数传递过来,赋值在此处。
*/
private Object target;
public Object getInstanceInit(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
//回调方法。
enhancer.setCallback( this);
//创建代理对象。
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("==========CGLIB 动态代理=========");
System.out.println("before reflect hello ...");
Object result = method.invoke(target,objects); //objects == args 即方法参数
System.out.println("after reflect hello ...");
return result;
}
}
public class CGLIBAOPMainTest {
public static void main(String[] args) {
HelloServiceCglibProxy helloHandler = new HelloServiceCglibProxy();
HelloService proxy = (HelloService) helloHandler.getInstanceInit(new HelloServiceImpl());
proxy.sayHello("张三");
}
}
==========CGLIB 动态代理=========
before reflect hello ...
Hello 张三,It's me !
after reflect hello ...