JDK代码
user类
package com.lb.spring.model;
public class User {
private String name;
private Integer age;
private String password;
public User() {
super();
}
public User(String name, Integer age, String password) {
super();
this.name = name;
this.age = age;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", password=" + password + "]";
}
}
package com.lb.spring.service;
public interface UserService {
public void save();
public void update();
}
UserService实现类
package com.lb.spring.serviceimpl;
import com.lb.spring.model.User;
import com.lb.spring.service.UserService;
public class UserServiceImpl
implements UserService {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void save() {
System.out.println("保存用户");
}
public void update() {
System.out.println("修改用户");
}
}
JDK动态代理类
package com.lb.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* JDK动态代理 必须实现 java.lang.reflect.InvocationHandler接口
*/
public class JDKProxy implements InvocationHandler {
/*
* 指定代理目标对象
*/
private Object targetObj;
/*
* 第一个参数:获得目标对象的类的加载器
* 第二个参数:获得目标对象的接口
* 第三个参数:设置回调对象,当前代理对象的方法被调用时,会委派该参数去调用invoke
*/
public Object createProxyInstance(Object targetObj) {
this.targetObj = targetObj;
return Proxy.newProxyInstance(this.targetObj.getClass().getClassLoader(),
this.targetObj.getClass().getInterfaces(), this);
}
/*
* proxy:代理类
* Method:要调用的业务方法
* Object[]:调用的业务方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//获得目标对象的get方法
Method getMeth = this.targetObj.getClass().getMethod("getUser", null);
//通过反射来调用getUser
Object user = getMeth.invoke(targetObj, null);
Object obj = null;
if(user != null) {
//obj是业务方法返回的值
obj = method.invoke(this.targetObj, args);
}else {
System.out.println("您还没有登录");
}
return obj;
}
}
JDK测试类
package com.lb.spring.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lb.spring.model.User;
import com.lb.spring.proxy.CGLIBProxy;
import com.lb.spring.proxy.JDKProxy;
import com.lb.spring.service.UserService;
import com.lb.spring.serviceimpl.UserServiceImpl;
public class TestSpring {
/*
* JDK动态代理
*/
@Test
public void test() {
UserServiceImpl ui = new UserServiceImpl();
ui.setUser(new User());
//通过业务接口来接收代理对象
UserService userService = (UserService) new JDKProxy().createProxyInstance(ui);
System.out.println(userService.getClass());
System.out.println("--------------------1");
userService.save();
}
CGLIB动态代理
UserService类
package com.lb.spring.serviceimpl;
import com.lb.spring.model.User;
import com.lb.spring.service.UserService;
public class UserServiceImpl
{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void save() {
System.out.println("保存用户");
}
public void update() {
System.out.println("修改用户");
}
}
CGLIB动态代理类
package com.lb.spring.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class CGLIBProxy implements MethodInterceptor {
/*
* 指定代理目标对象
*/
private Object targetObj;
public Object createProxyInstance(Object targetObj) {
this.targetObj = targetObj;
/*
* 以下四句代码记住即可,反正就是创建代理类对象的方法,底层不要多在意
*/
System.out.println("sssssssssss");
// 创建加强器,用来创建动态代理类
Enhancer enhancer = new Enhancer();
// 为代理类指定需要代理的类,也即是父类
System.out.println("aaaaaaaaaaaaaaaa");
enhancer.setSuperclass(this.targetObj.getClass());
//设置方法拦截器回调引用,对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept() 方法进行拦截
enhancer.setCallback(this);
// 创建cglib 代理类
return enhancer.create();
}
/*
* 重写intercept方法
* 参数分别为代理对象,目标对象方法,方法参数,代理对象方法
*/ @Override
public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
//获得目标对象的get方法
Method getMeth = this.targetObj.getClass().getMethod("getUser", null);
//利用反射机制,实现目标对象的方法调用
Object user = getMeth.invoke(targetObj, arg2);
Object obj = null;
if (user != null) {
//目标对象方法
obj = method.invoke(this.targetObj, arg2);
}else {
System.out.println("您还没有登录");
}
//返回方法执行后的返回值
return obj;
}
}
CGLIB测试类
package com.lb.spring.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lb.spring.model.User;
import com.lb.spring.proxy.CGLIBProxy;
import com.lb.spring.proxy.JDKProxy;
import com.lb.spring.service.UserService;
import com.lb.spring.serviceimpl.UserServiceImpl;
public class TestSpring {
/*
* CGLIB动态代理
*/
@Test
public void test1(){
UserServiceImpl ui1 = new UserServiceImpl();
ui1.setUser(new User());
System.out.println("---------------");
//通过业务接口来接收代理对象
UserServiceImpl userServiceImpl = (UserServiceImpl) new CGLIBProxy().createProxyInstance(ui1);
System.out.println(userServiceImpl.getClass());
System.out.println("---------------2");
userServiceImpl.save();
}
}
遇见的问题:
报异常需要引入jar