zoukankan      html  css  js  c++  java
  • aop学习总结一------使用jdk动态代理简单实现aop功能

    aop学习总结一------使用jdk动态代理实现aop功能

    动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码

    Jdk动态代理(proxy):目标对象必须实现接口,jdk的动态代理对象会默认实现目标对象的所有接口

    模拟业务需求:

     1.拦截所有业务方法

    2.判断用户是否有权限,有权限就允许用户执行业务方法,无权限不允许用户执行业务方法

    (判断是否有权限是根据user是否为null

    业务接口类:

    public interface PersonService {
    
        public void save(String name);
        public void update(String name,Integer personId);
        public String getPersonName(Integer personId);
    }

    业务接口实现类:

    import ql.service.PersonService;
    
    public class PersonServiceBean implements PersonService {
    
        private String user=null;
        
        public PersonServiceBean(){}
        
        public PersonServiceBean(String user){    
            this.user=user;
        }
    
        public String getUser() {
            return user;
        }
    
        public void setUser(String user) {
            this.user = user;
        }
    
        public void save(String name) {
    
            System.out.println("我是save()方法");
        }
    
        public void update(String name, Integer personId) {
            System.out.println("我是update()方法");
        }
    
        public String getPersonName(Integer personId) {
            System.out.println("我是getPersonName()方法");
            return "success";
        }
    
    }


    jdk代理对象工厂类:

    package ql.service.aop;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import ql.service.impl.PersonServiceBean;
    
    public class JDKProxyFactory implements InvocationHandler {
    
        //目标对象
        private Object targetObject;
        
        //得到一个代理实例
        public Object createProxyIntance(Object targetObject){
            
            this.targetObject=targetObject;
            //第一个参数:目标对象的类装载器
            //第二个参数:代理对象实现了的目标对象的接口,即目标对象的接口
            //第三个参数:接口回调,使用aop拦截时会触发哪个类的拦截方法,要去拦截类必须实现InvocationHandler接口
            return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this);
        }
    
        //被触发的拦截的方法
        /**
         * params:
         * proxy:代理对象
         * method:被拦截的方法
         * args:方法的输入参数        
         */
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            PersonServiceBean bean=(PersonServiceBean) targetObject;
            
            Object result=null;
            if (bean.getUser()!=null) {
                //执行目标对象的方法
                result=method.invoke(targetObject, args);
            }
            
            return result;
        }
        
    }

    单元测试类:

    package ql.test;
    
    
    import org.junit.Before;
    import org.junit.Test;
    
    import ql.service.PersonService;
    import ql.service.aop.JDKProxyFactory;
    import ql.service.impl.PersonServiceBean;
    
    public class ProxyTest {
    
        @Before
        public void setUp() throws Exception {
        }
    
        @Test
        public void testJDKProxyFactory1() {
            
            JDKProxyFactory factory=new JDKProxyFactory();
            PersonService service=(PersonService) factory.createProxyIntance(new PersonServiceBean() );
            service.save("小明");
        }
        @Test
        public void testJDKProxyFactory2() {
            
            JDKProxyFactory factory=new JDKProxyFactory();
            PersonService service=(PersonService) factory.createProxyIntance(new PersonServiceBean("xxx") );
            service.save("小明");
        }
    
    }
  • 相关阅读:
    Android开发切换host应用
    HTTP缓存相关头
    我理解的Android加载器
    Mysql的NULL的一个注意点
    Android的Activity生命周期
    说说jsonp
    PHP的pcntl多进程
    谈谈不换行空格
    关于Java代码优化的44条建议!
    java8 遍历数组的几种方式
  • 原文地址:https://www.cnblogs.com/ql211lin/p/4551960.html
Copyright © 2011-2022 走看看