-
动态代理
JDK 代码示例: 需求, user 实体类 值写入到数据库时, 校验name 长度不能小于1
无侵入性增强
- 有个接口 UserService
package com.enjoylearning.dynamic.proxy.jdk;
import com.enjoylearning.dynamic.proxy.User;
public interface UserService {
void addUser(User user);
}
- 被增强的类必须要继承接口
package com.enjoylearning.dynamic.proxy.jdk;
import com.enjoylearning.dynamic.proxy.User;
public class UserServiceImpl implements UserService {
@Override
public final void addUser(User user) {
System.out.println("用户数据入库成功,数据为:" + user.toString());
}
}
3.拦截器
package com.enjoylearning.dynamic.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import com.enjoylearning.dynamic.proxy.User;
public class UserServiceInterceptor implements InvocationHandler{
private Object realObj;
private static Logger logger = Logger.getLogger(UserServiceInterceptor.class.getName());
public Object getRealObj() {
return realObj;
}
public void setRealObj(Object realObj) {
this.realObj = realObj;
}
public UserServiceInterceptor(Object realObj) {
super();
this.realObj = realObj;
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
if(args!=null && args.length>0 && args[0] instanceof User){
User user = (User) args[0];
if(user.getName().trim().length()<=1){
throw new RuntimeException("用户姓名输入长度需要大于1!");
}
}
Object ret = method.invoke(realObj, args);
logger.info("数据库操作成功!");
return ret;
}
}
4.测试方法
package com.enjoylearning.dynamic.proxy.jdk;
import java.lang.reflect.Proxy;
import com.enjoylearning.dynamic.proxy.User;
public class Client {
public static void main(String[] args) {
User user = new User();
user.setAddress("地址");
user.setAge(20);
user.setName("1ison");
UserService us = new UserServiceImpl();
UserServiceInterceptor usi = new UserServiceInterceptor(us);
//1.类加载器
//2. 服务接口信息
//3. invocationhandler 本身
UserService proxy = (UserService) Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(), usi);
//通过动态代理增强业务
proxy.addUser(user);
// System.out.println("---------------------");
// System.out.println(proxy.hashCode());
}
}
CGLIB 动态代理
1.被增强的 方法, 不需要继承接口
package com.enjoylearning.dynamic.proxy.cglib;
import com.enjoylearning.dynamic.proxy.User;
public class UserServiceImpl {
public final void addUser(User user) {
System.out.println("用户数据入库成功,数据为:"+user.toString());
}
}
2.拦截器 实现intercept 方法
package com.enjoylearning.dynamic.proxy.cglib;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import com.enjoylearning.dynamic.proxy.User;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class UserServiceInterceptor implements MethodInterceptor {
private static Logger logger = Logger.getLogger(UserServiceInterceptor.class.getName());
public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
if(args!=null && args.length>0 && args[0] instanceof User){
User user = (User) args[0];
if(user.getName().trim().length() <= 1){
throw new RuntimeException("用户姓名输入长度需要大于1!");
}
}
Object ret = proxy.invokeSuper(obj, args);
logger.info("数据库操作成功!");
return ret;
}
}
- 测试类
package com.enjoylearning.dynamic.proxy.cglib;
import com.enjoylearning.dynamic.proxy.User;
import net.sf.cglib.proxy.Enhancer;
public class Client {
public static void main(String[] args) {
User user = new User();
user.setAddress("地址");
user.setAge(20);
user.setName("lison");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(new UserServiceInterceptor());
UserServiceImpl usi1 = (UserServiceImpl) enhancer.create();
usi1.addUser(user);
// System.out.println("---------------------");
// System.out.println(usi.hashCode());
// UserServiceImpl us = new UserServiceImpl();
// enhancer.setCallback(new UserServiceDelegateInterceptor(us));
// UserServiceImpl usi2 = (UserServiceImpl) enhancer.create();
// usi2.addUser(user);
}
}