一、jdk动态代理
1. 测试类
public class TestJdkProxy {
public static void main(String[] args) {
JdkProxy jdkProxy = new JdkProxy(new UserServiceImpl());
UserService userService =(UserService)jdkProxy.getProxyObject();
userService.hello("test");
}
}
测试结果:
jdk代理:hello
hello:test
2.代理类
public class JdkProxy implements InvocationHandler {
private Object tagetObject;
public JdkProxy(Object object){
this.tagetObject= object;
}
public Object getProxyObject(){
return Proxy.newProxyInstance(tagetObject.getClass().getClassLoader(),tagetObject.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk代理:" + method.getName());
//实际应用场景,可能不是这样用,而是自定义实现,比如:dubbo服务,因为没有实现类,需要通过代理的方式调用远程的服务。
return method.invoke(tagetObject, args);
}
}
3.接口类
public interface UserService {
void hello(String username);
void world(String username);
}
4.接口实现类
public class UserServiceImpl implements UserService {
@Override
public void hello(String username) {
System.out.println("hello:" + username);
}
@Override
public void world(String username) {
System.out.println("world:" + username);
}
}
二、cglib代理
1.测试类
public class Testcglib {
public static void main(String[] args) {
UserService userService = (UserService) new CglibProxy().createProxyObject(new UserServiceImpl());
System.out.println("测试hello方法");
userService.hello("test");
System.out.println("---------------");
System.out.println("测试world方法");
userService.world("test");
}
}
测试结果:
测试hello方法
hello:test
---------------
测试world方法
拦截方法,重写该方法:world
world:test
2.接口类
public interface UserService {
void hello(String username);
void world(String username);
}
3.接口实现类
public class UserServiceImpl implements UserService {
@Override
public void hello(String username) {
System.out.println("hello:" + username);
}
@Override
public void world(String username) {
System.out.println("world:" + username);
}
}
4.代理类
public class CglibProxy implements MethodInterceptor {
private Object targetObject;
public Object createProxyObject(Object obj) {
this.targetObject = obj;
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallbacks(new Callback[] { this, NoOp.INSTANCE });
e.setCallbackFilter(new UserCallbackFilter());
return e.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("拦截方法:"+method.getName());
return method.invoke(targetObject,args);
}
}
5.方法过滤器类
public class UserCallbackFilter implements CallbackFilter {
@Override
public int accept(Method method) {
if("world".equals(method.getName())) {
return 0;//会拦截,重写该方法字节码
}else {
return 1;//不会拦截,不会重写该方法字节码,直接调方法
}
}
}
总结:jdk代理只能对接口代理,cglib代理是针对类代理的。如果要代理的对象没有实现接口,那就只能用cglib代理了。
<aop:aspectj-autoproxy proxy-target-class=”true”/>,这个配置大家在spring中应该都见过,默认是jdk代理,它的意思是如果代理的目标是类,没有实现接口,那么就用cglib代理。
代理模式一般在底层框架实现上用的比较多,比如:dubbo框架的服务调用,mybatis框架的mapper接口调用。