一般代码
接口,实现
package priv.dengjl.proxy.bean;
public interface IPersonService {
void sayHello();
void printName();
void test();
}
package priv.dengjl.proxy.bean;
/**
* 业务代码,普通业务开发员工编写
*
* @author it
*/
public class PersonService implements IPersonService {
@Override
public void sayHello() {
System.out.println("sayHello");
}
@Override
public void printName() {
System.out.println("printName");
}
@Override
public void test() {
System.out.println("test");
throw new RuntimeException("抛出测试异常!!!");
}
}
测试类
package priv.dengjl.proxy.test;
import priv.dengjl.proxy.bean.IPersonService;
import priv.dengjl.proxy.bean.PersonService;
public class App {
public static void main(String[] args) {
IPersonService service = new PersonService();
System.out.println("====================");
service.sayHello();
System.out.println("====================");
service.printName();
System.out.println("====================");
service.test();
System.out.println("====================");
}
}
测试结果
====================
sayHello
====================
printName
====================
test
Exception in thread "main" java.lang.RuntimeException: 抛出测试异常!!!
at priv.dengjl.proxy.bean.PersonService.test(PersonService.java:23)
at priv.dengjl.proxy.test.App.main(App.java:15)
引入静态代理
对原业务类具备了控制作用
package priv.dengjl.proxy.highproxy;
import priv.dengjl.proxy.bean.IPersonService;
import priv.dengjl.proxy.bean.PersonService;
/**
* 系统控制,由高级业务人员编写
*
* 这里简单处理,直接继承PersonService,
* 使StaticPersonServiceProxy与PersonService保持类型一致,也可以不继承
*
* 这里是为了简化代码,未用接口
*
* @author it
*/
public class StaticPersonServiceProxy extends PersonService {
private IPersonService service;
public StaticPersonServiceProxy(IPersonService service) {
this.service = service;
}
@Override
public void sayHello() {
System.out.println("dobefore");
service.sayHello();
System.out.println("doafter");
}
@Override
public void printName() {
System.out.println("dobefore");
service.printName();
System.out.println("doafter");
}
@Override
public void test() {
System.out.println("dobefore");
try {
service.test();
} catch (Exception e) {
e.printStackTrace();
System.out.println("doException");
}
System.out.println("doafter");
}
}
测试类
package priv.dengjl.proxy.test;
import priv.dengjl.proxy.bean.IPersonService;
import priv.dengjl.proxy.bean.PersonService;
import priv.dengjl.proxy.highproxy.StaticPersonServiceProxy;
public class AppStaticProxy {
public static void main(String[] args) {
IPersonService service = new PersonService();
//静态代理类
IPersonService serviceProxy = new StaticPersonServiceProxy(service);
System.out.println("====================");
serviceProxy.sayHello();
System.out.println("====================");
serviceProxy.printName();
System.out.println("====================");
serviceProxy.test();
System.out.println("====================");
}
}
测试结果
====================
dobefore
sayHello
doafter
====================
dobefore
printName
doafter
====================
dobefore
test
java.lang.RuntimeException: 抛出测试异常!!!
doException
doafter
====================
at priv.dengjl.proxy.bean.PersonService.test(PersonService.java:23)
at priv.dengjl.proxy.highproxy.StaticPersonServiceProxy.test(StaticPersonServiceProxy.java:42)
at priv.dengjl.proxy.test.AppStaticProxy.main(AppStaticProxy.java:18)
引入动态代理
动态代理采用反射简化静态代理实现
package priv.dengjl.proxy.highproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import priv.dengjl.proxy.bean.IPersonService;
/**
* 系统控制,由高级业务人员编写
*
* 动态代理处理类
*
* @author it
*/
public class DynamicPersonServiceProxy implements InvocationHandler {
private IPersonService service;
public DynamicPersonServiceProxy(IPersonService service) {
this.service = service;
}
/**
* 代理了PersonService类所有方法,简化静态代理类
*
* @Override
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("dobefore");
try {
return method.invoke(service, args);
} catch (Exception e) {
e.printStackTrace();
System.out.println("doException");
}
System.out.println("doafter");
return null;
}
}
测试
package priv.dengjl.proxy.test;
import java.lang.reflect.Proxy;
import priv.dengjl.proxy.bean.IPersonService;
import priv.dengjl.proxy.bean.PersonService;
import priv.dengjl.proxy.highproxy.DynamicPersonServiceProxy;
public class AppDynamicProxy {
public static void main(String[] args) {
IPersonService service = new PersonService();
// 动态代理处理器
DynamicPersonServiceProxy serviceProxyHandler = new DynamicPersonServiceProxy(service);
IPersonService serviceProxy = (IPersonService) Proxy.newProxyInstance(serviceProxyHandler.getClass().getClassLoader(), service.getClass().getInterfaces(), serviceProxyHandler);
System.out.println("====================");
serviceProxy.sayHello();
System.out.println("====================");
serviceProxy.printName();
System.out.println("====================");
serviceProxy.test();
System.out.println("====================");
}
}
测试结果,与静态代理一模一样
====================
dobefore
sayHello
====================
dobefore
printName
====================
dobefore
test
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at priv.dengjl.proxy.highproxy.DynamicPersonServiceProxy.invoke(DynamicPersonServiceProxy.java:31)
at com.sun.proxy.$Proxy0.test(Unknown Source)
at priv.dengjl.proxy.test.AppDynamicProxy.main(AppDynamicProxy.java:22)
Caused by: java.lang.RuntimeException: 抛出测试异常!!!
at priv.dengjl.proxy.bean.PersonService.test(PersonService.java:23)
... 7 more
doException
doafter
====================
动态代理切入点,颗粒度控制代理
只代理一部分方法,不代理所有
package priv.dengjl.proxy.highproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import priv.dengjl.proxy.bean.IPersonService;
/**
* 系统控制,由高级业务人员编写
*
* 动态代理处理类
*
* @author it
*/
public class DynamicPersonServiceProxyPointcut implements InvocationHandler {
private IPersonService service;
public DynamicPersonServiceProxyPointcut(IPersonService service) {
this.service = service;
}
/**
* 代理了PersonService类中的printName方法
*
* @Override
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
// 只代理printName方法
if ("printName".equals(name)) {
Object object = null;
System.out.println("dobefore");
try {
object = method.invoke(service, args);
} catch (Exception e) {
e.printStackTrace();
System.out.println("doException");
}
System.out.println("doafter");
return object;
} else {
return method.invoke(service, args);
}
}
}
测试
package priv.dengjl.proxy.test;
import java.lang.reflect.Proxy;
import priv.dengjl.proxy.bean.IPersonService;
import priv.dengjl.proxy.bean.PersonService;
import priv.dengjl.proxy.highproxy.DynamicPersonServiceProxyPointcut;
public class AppDynamicProxyPointCut {
public static void main(String[] args) {
IPersonService service = new PersonService();
// 动态代理处理器,带有切面点的
DynamicPersonServiceProxyPointcut serviceProxyHandler = new DynamicPersonServiceProxyPointcut(service);
IPersonService serviceProxy = (IPersonService) Proxy.newProxyInstance(serviceProxyHandler.getClass().getClassLoader(), service.getClass().getInterfaces(), serviceProxyHandler);
System.out.println("====================");
serviceProxy.sayHello();
System.out.println("====================");
serviceProxy.printName();
System.out.println("====================");
serviceProxy.test();
System.out.println("====================");
}
}
测试结果
====================
sayHello
====================
dobefore
printName
doafter
====================
test
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy0.test(Unknown Source)
at priv.dengjl.proxy.test.AppDynamicProxyPointCut.main(AppDynamicProxyPointCut.java:22)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at priv.dengjl.proxy.highproxy.DynamicPersonServiceProxyPointcut.invoke(DynamicPersonServiceProxyPointcut.java:45)
... 2 more
Caused by: java.lang.RuntimeException: 抛出测试异常!!!
at priv.dengjl.proxy.bean.PersonService.test(PersonService.java:23)
... 7 more