Spring Aop(入门篇)

  1. Aop:简称面向切面编程,这是Spring的一个关键性的组件。Spring Aop的出现是为了取代EJB中的事物机制,它有这种声明式的事务机制,Aop提供另外一种角度来思考程序结构,通过这种方式弥补了面对对象(OOP)的不足。
  2. 在实际开发过程中,往往常见Aop的需求:(1)比如写系统日志,便于我们查看系统的运行情况(2)安全校验,进行权限校验或者非空校验(3)性能优化(4)错误、异常处理
  3. Aop的使用特色:专门用于扩展系统功能,这样就不用去修改OOP编程已经写好的代码,符合高内聚的开发要求。
  4. 以下说明两种动态生成代理对象的方法

(1)jdk中有个著名的类:Proxy类,代理类,专门用来动态生成代理对象(面对接口编程)

  • /**
     *创建一个User接口
     */

    public interface UserDao {
        public void addUser();
        public void queryUser();
    }
     

  • /**
     * 定义接口实现类,以下无具体实现代码,为了测试使用
     * @author hp
     *
     */

    public class UserDaoImpl implements UserDao {

        @Override
        public void addUser() {
            System.out.println("--- adduser ----");

        }

        @Override
        public void queryUser() {
            System.out.println("--- queryuser ----");

        }

    }

  • /**
     * 
     * 创建jdk代理工厂类,需要实现InvocationHandler这个接口
     * @author hp
     *
     */

    public class ProxyFactory implements InvocationHandler{
        //获取日志log,需要获取本类的路径
        Logger log = Logger.getLogger("cn.neusoft.spring.proxy.ProxyFactory"); 
        //需要先声明一个目标对象
        private Object targetObject;
        public  Object getProxyObject(Object targetObject){
            this.targetObject = targetObject;
            /**
             * 返回一个重构类对象(代理对象),其中三大参数:类加载器,类需要实现的接口,返回本类
             * targetObject.getClass().getClassLoader():目标对象的类加载器,方便对目标对象进行改造 
             * targetObject.getClass().getInterfaces():代理对象需要实现和目标对象一样的接口,所以需要获取目标对象实现了哪             些接口 
             * this:代表当前对象
             */
     
            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
        }
        @Override
        //在invoke方法中可以方便的扩展目标对象的相关方法的功能
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            log.log(Level.INFO,"访问-----"+method.getName()+"开始");
            //调用执行
            Object result = method.invoke(this.targetObject, args);
            log.log(Level.INFO,"访问-----"+method.getName()+"结束");
            return result;
        }

    }
     

  • /**
     * 测试代理工厂类
     * @author hp
     *
     */

    public class TestProxyFactory {

        public static void main(String[] args) {
            //1.实例化化实现类对象
            UserDao userDao = new UserDaoImpl();
            //2.实例化抽象工厂
            ProxyFactory pf = new ProxyFactory();
            //通过抽象工厂,返回代理对象
            UserDao userdao = (UserDao)pf.getProxyObject(userDao);
            userdao.addUser();

        }

    }
     

(2)万一是单例模式的话,面对对象编程实现代理工厂类的话,不能再用jdk实现,需要借助第三方jar包去实现

    cglib的jar包以及asm的jar包实现(务必导入这两个包,必注意版本问题,可能有些版本会冲突,导致运行出错)

  • /*
     * 定义一个实现类EmpDaoImpl
     */

    public class EmpDaoImpl {
        public void deleteEmp(int empNo){
            System.out.println("---deleteEmp-----");
        }
        public void queryEmp(){
            System.out.println("---queryEmp-----");
        }
    }
     
  • /**
     * 定义CglibProxFactory类,来模拟Cglib包下代理工厂的写法
     * @author hp
  •  *
     */

    public class CglibProxFactory implements MethodInterceptor{
        //获取日志小log 
        Logger log = Logger.getLogger("cn.neusoft.spring.proxy.CglibProxFactory");
        //声明一个对象
        private Object taget;
        //生成代理对象方法,这是cglib中跟jdk中不同的写法
        public Object getProxObject(Object target){
            this.taget=target;
            Enhancer  enhancer = new Enhancer();
            enhancer.setSuperclass(taget.getClass());//设置taget这个类
            enhancer.setCallback(this);//设置回调函数
            return enhancer.create();//返回这个enhancer的类
            
        }
        @Override
        public Object intercept(Object object, Method method, Object[] args,
                MethodProxy methodProxy) throws Throwable {
            //获取方法中的参数
            System.out.println("args"+Arrays.toString(args));
            log.log(Level.INFO,"开始-----"+method.getName());
            //打印第一个参数:会陷入死循环(可能为了防止观察它的具体信息)
            //System.out.println("proxy:"+proxy);
            System.out.println("方法名字"+method.getName());
            log.log(Level.INFO,"结束-----"+method.getName());
            //打印第四个参数:会陷入死循环(可能为了防止观察它的具体信息)
            //System.out.println("methodProxy:"+methodProxy.getClass().getName());
            return null;
        }
            
    }
  • /**
     * 定义一个测试类TestCglibProxFactory
     * @author hp
     *
     */

    public class TestCglibProxFactory {
        public static void main(String args[]){
            //注意这里实例化实现类,不再是接口类型
            EmpDaoImpl empImpl = new EmpDaoImpl();
            CglibProxFactory cglibProx = new CglibProxFactory();
            EmpDaoImpl empImpProxDaoImpl= (EmpDaoImpl) cglibProx.getProxObject(empImpl);
            empImpProxDaoImpl.deleteEmp(11);
        }
    }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值