动态代理方法:
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 测试动态代理
* @author Administrator
*/
public class DynamicProxy implements InvocationHandler {
/**
* 动态代理对象
*/
private Object target;
private List<String> needReturnProxy = new ArrayList<>();
public DynamicProxy() {
}
/**
* 构造器注入代理对象
* @param target 动态代理对象
*/
public DynamicProxy(Object target) {
this.target = target;
}
/**
* 获取代理接口对象
* @return 返回代理接口对象
*/
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
printBeforeMsg();
execBeforeMethod();
Object obj = method.invoke(target, args);
printAfterMsg();
execAfterMethod();
if(CollectionUtils.contains(needReturnProxy.listIterator(), method.getName())){
return proxy;
}
return obj;
}
/**
* 前置打印消息集合
*/
private String[] beforeMsg;
/**
* 设置前置消息
* @param beforeMsg 前置消息
*/
public void setBeforeMsg(String[] beforeMsg) {
this.beforeMsg = beforeMsg;
}
/**
* 前置打印消息方法
*/
private void printBeforeMsg(){
if (beforeMsg==null) {
return;
}
for (String msg : beforeMsg) {
if(StringUtils.isEmpty(msg)){
return;
}
System.out.println(msg);
}
}
/**
* 前置执行方法集合
*/
private Set<List<Object>> beforeMethod;
/**
* 设置前置执行方法
* @param beforeMethod 前置执行方法
*/
public void setBeforeMethod(Set<List<Object>> beforeMethod) {
this.beforeMethod = beforeMethod;
}
/**
* 执行前置方法
*/
private void execBeforeMethod(){
if(beforeMethod==null || beforeMethod.isEmpty()){
return;
}
for (List<Object> list : beforeMethod) {
try{
Method method = (Method)list.get(0);
Object obj = list.get(1);
Object[] args = (Object[])list.get(2);
method.invoke(obj, args);
} catch (Exception e){
System.out.println("beforeSet报错");
e.printStackTrace();
}
}
}
/**
* 后置打印消息集合
*/
private String[] afterMsg;
/**
* 设置后置消息
* @param afterMsg 后置消息
*/
public void setAfterMsg(String[] afterMsg) {
this.afterMsg = afterMsg;
}
/**
* 后置打印消息方法
*/
private void printAfterMsg(){
if (afterMsg==null) {
return;
}
for (String msg : afterMsg) {
if(StringUtils.isEmpty(msg)){
return;
}
System.out.println(msg);
}
}
/**
* 后置执行方法集合
*/
private Set<List<Object>> afterMethod;
/**
* 设置后置执行方法
* @param afterMethod 后置执行方法
*/
public void setAfterMethod(Set<List<Object>> afterMethod) {
this.afterMethod = afterMethod;
}
/**
* 执行后置方法
*/
private void execAfterMethod(){
if(afterMethod==null || afterMethod.isEmpty()){
return;
}
for (List<Object> list : afterMethod) {
try{
Method method = (Method)list.get(0);
Object obj = list.get(1);
Object[] args = (Object[])list.get(2);
method.invoke(obj, args);
} catch (Exception e){
System.out.println("afterSet报错");
e.printStackTrace();
}
}
}
/**
* 设置需要返回代理对象的方法名
* @param needReturnProxy 方法名
*/
public void setNeedReturnProxy(List<String> needReturnProxy) {
this.needReturnProxy = needReturnProxy;
}
}
Person测试接口:
public interface Person {
/**
* 打印名字
*/
void name();
}
两个实现类:
小明实现Person
public class XiaoMing implements Person {
@Override
public void name() {
System.out.println("=====我叫小明=====");
}
}
小红实现Person
public class XiaoHong implements Person{
@Override
public void name() {
System.out.println("=====我叫小红=====");
}
}
测试类:
import java.util.*;
public class TestPerson {
public static void main(String[] args) {
try{
XiaoMing xiaoMing = new XiaoMing();
XiaoHong xiaoHong = new XiaoHong();
DynamicProxy dynamicProxy = new DynamicProxy(xiaoMing);
Person proxy = (Person)dynamicProxy.getProxy();
//设置参数
List<Object> ls = new ArrayList<>();
ls.add(xiaoHong.getClass().getMethod("name"));
ls.add(xiaoHong);
ls.add(null);
Set<List<Object>> set = new HashSet<>();
set.add(ls);
//将小红的name方法在小明的代理方法之前调用
dynamicProxy.setBeforeMethod(set);
//将小红的name方法在小明的代理方法之后调用
dynamicProxy.setAfterMethod(set);
//代理执行name方法
proxy.name();
} catch (Exception e){
e.printStackTrace();
}
}
}
执行结果:
=====我叫小红=====
=====我叫小明=====
=====我叫小红=====
结论:动态代理是通过反射机制去调用被代理的实例对象的方法。代理只能在方法之间切入,不能在方法里切入。
注:小红的类只是顺手写的实现Person接口,并不是一定需要实现这个接口。
标签:return,void,Object,代理,private,动态,public From: https://www.cnblogs.com/lizhenfeng/p/17103706.html