Java动态代理(三)——模拟AOP实现
2024-08-31 23:09:14
以下案例模拟AOP实现
目录结构
接口PersonService
package com.ljq.service; public interface PersonService {
public void save(String name);
public void update(String name, Integer personId);
public String getPersonName(Integer personId);
}
实现类PersonServiceBean
package com.ljq.service.impl; import com.ljq.service.PersonService; public class PersonServiceBean implements PersonService {
private String user = null; public PersonServiceBean() {
super();
} public PersonServiceBean(String user) {
super();
this.user = user;
} public String getPersonName(Integer personId) {
System.out.println("我是getPersonName()方法");
return "get";
} public void save(String name) {
System.out.println("我是save()方法");
} public void update(String name, Integer personId) {
System.out.println("我是update()方法");
} public String getUser() {
return user;
} public void setUser(String user) {
this.user = user;
}
}
动态代理类JDKProxyFactory
package com.ljq.aop; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import com.ljq.service.impl.PersonServiceBean; public class JDKProxyFactory implements InvocationHandler {
//要代理的原始对象
private Object targer; /**
* 创建动态代理
*
* @param targer 要代理的原始对象
* @return
*/
public Object createProxyInstance(Object targer){
this.targer=targer;
return Proxy.newProxyInstance(
this.targer.getClass().getClassLoader(),
this.targer.getClass().getInterfaces(),
this);
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
PersonServiceBean bean = (PersonServiceBean) this.targer;
if (bean.getUser() != null) {
// 前置通知
doBefore();
try {
result = method.invoke(targer, args);
// 后置通知
doAfter();
} catch (Exception e) {
// 例外通知
doException();
} finally {
// 最终通知
doFinally();
}
}
return result;
} private void doBefore() {
System.out.println("我是前置通知");
} private void doAfter() {
System.out.println("我是后置通知");
} private void doException() {
System.out.println("我是例外通知");
} private void doFinally() {
System.out.println("我是最终通知");
} }
动态代理类CGlibProxyFactory:使用CGLIB技术
package com.ljq.aop; import java.lang.reflect.Method; import com.ljq.service.impl.PersonServiceBean; import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class CGlibProxyFactory implements MethodInterceptor{
private Object target; public Object createProxyInstance(Object target){
this.target=target;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.target.getClass());//非final
enhancer.setCallback(this);
return enhancer.create();
} public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object result=null;
PersonServiceBean bean=(PersonServiceBean)this.target;
if(bean.getUser()!=null){
// 前置通知
doBefore();
try {
result = methodProxy.invoke(target, args);
// 后置通知
doAfter();
} catch (Exception e) {
// 例外通知
doException();
} finally {
// 最终通知
doFinally();
}
}
return result;
} private void doBefore() {
System.out.println("我是前置通知");
} private void doAfter() {
System.out.println("我是后置通知");
} private void doException() {
System.out.println("我是例外通知");
} private void doFinally() {
System.out.println("我是最终通知");
} }
测试类AopTest
package com.ljq.test; import com.ljq.aop.CGlibProxyFactory;
import com.ljq.aop.JDKProxyFactory;
import com.ljq.service.PersonService;
import com.ljq.service.impl.PersonServiceBean; public class AopTest { public static void main(String[] args) {
proxyTest();
proxyTest2();
} private static void proxyTest() {
JDKProxyFactory jdkProxyFactory=new JDKProxyFactory();
PersonService personService=(PersonService)jdkProxyFactory.
createProxyInstance(new PersonServiceBean("zhangsan"));
personService.getPersonName(1);
} private static void proxyTest2() {
CGlibProxyFactory cglibProxyFactory=new CGlibProxyFactory();
PersonServiceBean bean=(PersonServiceBean)cglibProxyFactory.
createProxyInstance(new PersonServiceBean("lisi"));
bean.save("a"); }
}
运行结果
最新文章
- 初识node.js
- PhpStorm下Laravel代码智能提示
- 【linux】vim的一些快捷键
- CCLabel在最大宽度已知的情况下如何获取实际宽高
- Scala 深入浅出实战经典 第49课 Scala中Variance代码实战(协变)
- Java学习之路(一)
- Windows 2008 R2防火墙,允许被ping
- ChinaASP.Upload 错误 '80040002' You must add our copyright info
- git - 搭建git仓库
- 100个linux站点
- gdb调试python
- GMap获取可视范围内四个角的坐标
- 使用JSDoc自动生成代码文档
- 第二周学习总结-Java
- 腾讯云主机及CentOS7.2简单上手体验
- 导入另一个 Git库到现有的Git库并保留提交记录
- Bootstrap输入框组
- 每日英语:4G in China: A bigger deal than the iPhone
- servlet和JSP页面乱码问题
- Enter键登录