1 JDK动态代理(必须要有接口)
- 接口
package com.itykd.dao;
public interface UserDao {
void save();
void update();
void find();
void delete();
}
- 实现类
package com.itykd.dao.impl;
import com.itykd.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("UserDaoImpl的save方法执行了.....");
}
@Override
public void update() {
System.out.println("UserDaoImpl的update方法执行了.....");
}
@Override
public void find() {
System.out.println("UserDaoImpl的find方法执行了.....");
}
@Override
public void delete() {
System.out.println("UserDaoImpl的delete方法执行了.....");
}
}
- 提供一个JDK代理类需要继承InvocationHandler接口,并实现invoke方法,这里对Dao的save方法进行增强,Proxy的newProxyInstance方法提供三个参数创建UserDao对象,第一个参数是类加载器,第二个参数是接口
package com.itykd.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.itykd.dao.UserDao;
public class JDKProxy implements InvocationHandler{
//将被增强的对象传递到代理中
private UserDao userDao;
public JDKProxy(UserDao userDao) {
super();
this.userDao = userDao;
}
public UserDao createProxy() {
UserDao userDaoProxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断方法是否是save
if("save".equals(method.getName())) {
//增强
System.out.println("权限校验......");
return method.invoke(userDao, args);
}
return method.invoke(userDao, args);
}
}
- 测试代码
package com.itykd.proxy;
import org.junit.Test;
import com.itykd.dao.UserDao;
import com.itykd.dao.impl.UserDaoImpl;
public class ProxyDemo {
@Test
public void jdkProxyDemo() {
UserDao userDao = new UserDaoImpl();
//创建代理
UserDao userDaoProxy = new JDKProxy(userDao).createProxy();
userDaoProxy.save();
userDaoProxy.find();
userDaoProxy.delete();
userDaoProxy.update();
}
}
2 Cglib动态代理(继承的形式生成代理对象)
cglib是第三方开源代码生成类库,动态添加类的属性和方法(原来Hibernate也是用cglib做延迟加载,现在使用的是Javassist技术),Spring的核心包下已经有了Cglib的环境
- 目标类(要增强的类)
package com.itykd.dao;
public class ProductDao {
public void save() {
System.out.println("ProductDao的save方法执行了....");
}
public void update() {
System.out.println("ProductDao的update方法执行了....");
}
public void delete() {
System.out.println("ProductDao的delete方法执行了....");
}
public void find() {
System.out.println("ProductDao的find方法执行了....");
}
}
- cglib代理类
package com.itykd.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.itykd.dao.ProductDao;
public class CglibProxy implements MethodInterceptor{
private ProductDao productDao;
public CglibProxy(ProductDao productDao) {
super();
this.productDao = productDao;
}
public ProductDao createProxy() {
//1 创建cglib的核心类对象
Enhancer enhancer = new Enhancer();
//2 设置父类
enhancer.setSuperclass(productDao.getClass());
//3 设置回调:(类似于InvocationHandler对象)
enhancer.setCallback(this);
//4 创建代理对象
ProductDao productDaoProxy = (ProductDao)enhancer.create();
return productDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//判断方法是否为save
if("save".equals(method.getName())) {
//增强
System.out.println("权限校验...........");
return methodProxy.invokeSuper(proxy, args);
}
return methodProxy.invokeSuper(proxy, args);
}
}
- 测试类
package com.itykd.proxy;
import org.junit.Test;
import com.itykd.dao.ProductDao;
public class ProxyDemo {
public void cglibProxyDemo() {
ProductDao productDao = new ProductDao();
ProductDao productDaoProxy = new CglibProxy(productDao).createProxy();
productDaoProxy.save();
productDaoProxy.find();
productDaoProxy.delete();
productDaoProxy.update();
}
}