zoukankan      html  css  js  c++  java
  • Java动态代理(三)——模拟AOP实现

    以下案例模拟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");

    }
    }

    运行结果

     

  • 相关阅读:
    查看Eclipse版本号的方法
    设置Eclipse的字体风格方式
    又遇两个小异常
    我所推崇的三种心态
    关于javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>
    Http请求中Content-Type讲解
    ftp实现文件上传(下载)
    解析html文档的java库及范例
    xslt循环转换子元素
    XPath学习:轴(1)——child
  • 原文地址:https://www.cnblogs.com/doudouxiaoye/p/5685067.html
Copyright © 2011-2022 走看看