使用动态代理和cglib分别实现对类的代理
package com.example.service;
public interface UserService {
void add();
void delete();
void update();
void select();
}
package com.example.service;
public class UserServiceImpl implements UserService {
@Override
public void add() {
/**
* 正常工作场景add前需要打开事务,add后需要提交事务
* 这里我交给动态代理和cglib代理需要怎么操作呢?
*/
//System.out.println("打开事务");
System.out.println("新增用户");
//System.out.println("提交事务");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void select() {
System.out.println("查找用户");
}
}
package com.example.proxy;
import com.example.service.UserService;
import com.example.service.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//增强的接口这里由本身来实现
//动态代理类
public class UserServiceProxyFactory implements InvocationHandler{
//传入代理实例
private UserService us;
public UserServiceProxyFactory(UserService us) {
this.us = us;
}
/**
* 动态代理方法
*/
//定义一个工厂方法,返回一个UserService代理对象
public UserService getUserServiceProxy(){
//生成动态代理 类加载器 活动被加载对象实现的接口 增强的接口
UserService userProxy =(UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(), this);
return userProxy;
}
/**
*
* @param proxy 当前代理对象 UserServiceProxyFactory
* @param method 当前方法 getUseServiceProxy
* @param args 当前方法返回的参数 UserService类型的 userProxy
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//返回实例us
System.out.println("打开事务");
Object invoke = method.invoke(us,args);
System.out.println("关闭事务");
return null;
}
}
package com.example.proxy;
import com.example.service.UserService;
import com.example.service.UserServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
//cglib代理类
public class UserServiceProxyFactory2 implements MethodInterceptor {
/**
* cglib代理
* spring整合了cglib包,cglib包核心类Enhancer
* cglib继承类实现
*/
public UserService getUserServiceProxy(){
Enhancer enhancer = new Enhancer();//帮我们生成代理对象
enhancer.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
enhancer.setCallback(this);//代理要做什么,要求得到一个callback接口。交由本身去实现
UserService us = (UserService) enhancer.create();//创建代理对象
return us;
}
//实现enhancer.setCallback();接口。传来了四个参数。实现其MethodInterceptor方法
@Override
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
//打开事务
System.out.println("打开事务");
//调用原有方法
Object returnValue = methodProxy.invokeSuper(obj,arg);
//提交事务
System.out.println("提交事务");
return returnValue;
}
}
package com.example.proxy;
import com.example.service.UserService;
import com.example.service.UserServiceImpl;
import org.junit.Test;
public class Demo03 {
@Test
public void proxyTest() {
UserService us = new UserServiceImpl();
UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
UserService userProxy = factory.getUserServiceProxy();
//调用增加方法
userProxy.add();
//代理对象与被代理对象实现了相同的接口 false
//动态代理中 代理对象与被代理对象没有没有继承关系,仅是实现了同一个接口
System.out.println(userProxy instanceof UserServiceImpl);
}
@Test
public void proxyTest2() {
UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
UserService userProxy = factory.getUserServiceProxy();
//调用增加方法
userProxy.add();
//判断代理对象是否属于被代理对象类型
//cglib代理对象继承了被代理对象 true
System.out.println(userProxy instanceof UserServiceImpl);
}
}
- 动态代理(其局限性,被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术)
Proxy.newProxyInstance(classLoader.Interface[] arr,InvocationMandeler handler)
- cglib代理(其优点,作为第三方代理技术,cglib可以对任何类生成代理,代理的原理是对目标对象进行继承代理。但如果目标是被final修饰符修饰,那么该类无法被cglib代理)
总结,有接口存在时,优先使用动态动态,无接口时用cglib代理。