接口设计:
public interface UserService {
public void getUser();
}
接口实现类:
public class UserServiceImpl implements UserService{
public void getUser() {
System.out.println(1);
}
}
代理类:
package com.etc.spring.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.etc.spring.service.UserService;
import com.etc.spring.service.impl.UserServiceImpl;
public class UserServiceImpProxy {
/**
* java代理模式分为JDK动态代理和CGLib代理、静态代理
* 代理都是基于接口模式实现的
* @param userServiceImpl
* @return
*/
public static UserService getProxyObject(final UserService userServiceImpl){
//三个参数目标类的类加载器、目标类的接口、InvocationHandler对象
UserService userService = (UserService)Proxy.newProxyInstance(userServiceImpl.getClass().getClassLoader(), userServiceImpl.getClass().getInterfaces(), new InvocationHandler() {
//匿名内部类实现
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//可以在调用目标对象的前后,加上自己需要的日志
System.out.println("记录开始................");
Object object = method.invoke(userServiceImpl, args);
System.out.println("记录结束................");
return object;
}
});
return userService;
}
/**
* cglib需要用到Enhanceer创建增强器
* cglib是基于继承的方式实现的
* @param userService
* @return
*/
public static UserService getProxyByCGLib(UserService userService){
//创建增强器
Enhancer enhancer = new Enhancer();
//设置需要增强类的对象
enhancer.setSuperclass(UserService.class);
//调用回调方法
enhancer.setCallback(new MethodInterceptor() {
//代理对象是目标对象的子类
//MethodProxy代理之后的对象的方法引用
public Object intercept(Object object, Method method, Object[] arg2, MethodProxy proxy) throws Throwable {
System.out.println("cglib开始...............");
UserService userService = (UserService)proxy.invokeSuper(object, arg2);
System.out.println("cglib结束...............");
return userService;
}
});
//获取增强之后的代理对象
UserService userService2 = (UserService)enhancer.create();
return userService2;
}
}
测试类:
@org.junit.Test
public void test2(){
System.out.println("jdk动态代理测试...........");
//创建目标对象
UserService service = new UserServiceImpl();
//生成代理对象
UserService proxy = UserServiceImpProxy.getProxyObject(service);
//调用目标对象方法
service.getUser();
//调用代理对象方法
proxy.getUser();
System.out.println("cglib动态代理测试..........");
UserService service2 = new UserServiceImpl();
UserService cgService = UserServiceImpProxy.getProxyByCGLib(service2);
service2.getUser();
cgService.getUser();
}
输出:
jdk动态代理测试...........
1
记录开始................
1
记录结束................
cglib动态代理测试..........
1
cglib开始...............
=============================
jdk动态代理只能基于接口,cglib比较好用,不一定只基于接口,可以基于继承。spring aop原理就是基于动态代理来实现。有接口就用jdk代理实现,没有接口就用cglib实现。