JDK动态代理是基于面向接口编程,Spring AOP的实现也是基于此原理,而动态代理的实现则是基于反射机制。动态代理的主要目的就是灵活的将方法的调用与实现之间解耦,同时在目标方法调用的前后加入其他的通知。先看一个小demo:
先写一个系统用户的实体类SysUser
public class SysUser implements Serializable{
private String userId;
private String userName;
private String userPassword;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPasPord) {
this.userPasswo=userPasswd
这里也可以不实现序列化的,是我的项目加了redis所以才这么做。再写一个业务接口:
package com.my.ssm.service;
public interface DynamicService {
void Proxy(String s);
}
再写它的具体实现:
package com.my.ssm.impl;
import com.my.ssm.service.DynamicService;
public class Dyncmicimpl implements DynamicService {
@Override
public void Proxy(String s) {
System.out.println("动态代理调用::"+s);
}
}
接下来写动态代理接口InvocationHandler的实现类:
package com.my.ssm.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyDynamicTest implements InvocationHandler {
private Object targetObject;
public MyDynamicTest(Object object){
this.targetObject = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理前置通知");
method.invoke(targetObject,args);
System.out.println("动态代理后置通知");
return null;
}
}
关于invoke方法的几个参数在这里解释一下: Object proxy是代理对象的实例,Method method是对象的方法,Object [] args是方法的参数集。
再写一个测试类:
package com.my.ssm.test
import com.my.ssm.impl.Dyncmicimpl
import com.my.ssm.service.DynamicService
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Proxy
public class ProxyTest {
public static void main(String[] args){
//得到接口的实现
DynamicService dynamicService = new Dyncmicimpl()
//得到动态代理类
InvocationHandler invocationHandler = new MyDynamicTest(dynamicService)
//得到动态代理类创建的对象
DynamicService dynamicServiceProxy = (DynamicService) Proxy.newProxyInstance(DynamicService.class.getClassLoader(),new Class[]{DynamicService.class},invocationHandler)
//调用代理方法
dynamicServiceProxy.Proxy("动态代理")
}
}
运行结果:
动态代理前置通知
动态代理调用::动态代理
动态代理后置通知