一、JDK动态代理
1.1 原理
java动态代理是利用反射机制
生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
1.2 示例代码
package proxy;
import java.io.Serializable;
public class User implements Serializable {
private String name;
private Integer age;
//省略set、get方法
//省略toString()方法
}
package proxy;
public interface UserService {
String addUser(User user);
Integer deleteUser();
}
package proxy;
public class UserServiceImpl implements UserService {
@Override
public String addUser(User user) {
System.out.println("添加用户");
return user.toString();
}
@Override
public Integer deleteUser() {
System.out.println("删除用户");
return 1;
}
}
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserProxyFactory {
public static UserService createUserService(){
UserService userService = new UserServiceImpl();
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
/**
*
* @param proxy 代理对象
* @param method 被代理得方法
* @param args 被代理方法得参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
startTrans();
Object returnObj = method.invoke(userService, args);
commitTrans();
return returnObj;
}
});
return userServiceProxy;
}
public static void startTrans(){
System.out.println("开启事务");
}
public static void commitTrans(){
System.out.println("提交事务");
}
}
package proxy;
public class Test1 {
public static void main(String[] args) {
UserService userService = UserProxyFactory.createUserService();
User user1 = new User();
user1.setName("zhangsan");
user1.setAge(11);
String s = userService.addUser(user1);
System.out.println("s = " + s);
userService.deleteUser();
}
}
==>
开启事务
添加用户
提交事务
s = User{name='zhangsan', age=11}
开启事务
删除用户
提交事务
或者
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserProxyFactory1 implements InvocationHandler{
private UserService userService;
public UserProxyFactory1(UserService userService) {
this.userService = userService;
}
public UserService createUserService(){
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), userService.getClass().getInterfaces(), this);
return userServiceProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object returnObj = method.invoke(userService, args);
System.out.println("提交事务");
return returnObj;
}
}
package proxy;
public class Test2 {
public static void main(String[] args) {
UserProxyFactory1 userProxyFactory1 = new UserProxyFactory1(new UserServiceImpl());
UserService userService = userProxyFactory1.createUserService();
User user1 = new User();
user1.setName("lisi");
user1.setAge(12);
String s = userService.addUser(user1);
System.out.println("s = " + s);
userService.deleteUser();
}
}
1.3 优缺点
优点:
- 方法简单
- 无需第三方jar包就可以实现
缺点: - 被代理对象必须实现接口
二、cglib动态代理
2.1 原理
利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类
来处理。
2.2 示例代码
package com.onlymark.proxy;
import com.onlymark.service.UserService;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @auther Onlymark
* @date 2021/5/7 上午6:05
*/
public class JavaProxyFactory {
//cglib
public static UserService createUserServiceProxy(){
Enhancer enhancer = new Enhancer();
//设置Enhancer对象的父类
enhancer.setSuperclass(UserService.class);
//设置回调方法
enhancer.setCallback(new MethodInterceptor() {
/**
* obj:cglib生成的代理对象
* method:被代理对象方法
* args:方法入参
* methodProxy: 代理方法
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
System.out.println(method.toString());//debug模式下,会多次拦截。因为intercept方法会拦截UserService的所有方法(包括hashcode() toString()等)
Object object = methodProxy.invokeSuper(obj, args);
System.out.println("关闭事务");
return object;
}
});
//创建代理对象
UserService service = (UserService)enhancer.create();
//返回代理对象
return service;
}
public static void main(String[] args) {
UserService userServiceProxy = createUserServiceProxy();
userServiceProxy.adduser();
userServiceProxy.deleteuser();
}
}
或
package com.onlymark.proxy;
import com.onlymark.service.UserService;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @auther Onlymark
* @date 2021/5/7 上午6:05
*/
public class JavaProxyFactory1 implements MethodInterceptor {
private UserService userService;
public JavaProxyFactory1(UserService userService) {
this.userService = userService;
}
//cglib
public UserService createUserServiceProxy(){
Enhancer enhancer = new Enhancer();
//设置Enhancer对象的父类
enhancer.setSuperclass(UserService.class);
//设置回调方法
enhancer.setCallback(this);
//创建代理对象
UserService service = (UserService)enhancer.create();
//返回代理对象
return service;
}
/**
* obj:cglib生成的代理对象
* method:被代理对象方法
* args:方法入参
* methodProxy: 代理方法
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
Object object = method.invoke(userService, args);
System.out.println("关闭事务");
return object;
}
public static void main(String[] args) {
JavaProxyFactory1 javaProxyFactory1 = new JavaProxyFactory1(new UserService());
UserService userServiceProxy = javaProxyFactory1.createUserServiceProxy();
userServiceProxy.adduser();
userServiceProxy.deleteuser();
}
}
2.3 优缺点
优点:
- CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。
- CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理:
缺点: - 需要导入相关jar包,现已继承于spring-core.jar