码迷,mamicode.com
首页 > 编程语言 > 详细

Spring_Aop

时间:2018-12-19 01:09:53      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:流行   span   抽象   void   logging   div   cat   4.0   com   

为什么需要AOP?

  需求加减乘除

package com.tanlei.spring.bean.Aop;

public interface AtithmeticCalculator {
    int add(int i,int j);
    int sub(int i,int j);
    int mul(int i,int j);
    int div(int i,int j);
}

 

技术分享图片
package com.tanlei.spring.bean.Aop;

public class AtithmeticCalculatorImpl implements AtithmeticCalculator{

    @Override
    public int add(int i, int j) {
        System.out.println("the method add begin whith ["+i+","+j+"]");
        int result=i+j;
        System.out.println("the method add end whith"+result);
        return result;
    }

    @Override
    public int sub(int i, int j) {
        System.out.println("the method sub begin whith ["+i+","+j+"]");
        int result=i-j;
        System.out.println("the method sub end whith"+result);
        return result;
    }

    @Override
    public int mul(int i, int j) {
        System.out.println("the method mul begin whith ["+i+","+j+"]");
        int result=i*j;
        System.out.println("the method mul end whith"+result);
        return result;
        
    }

    @Override
    public int div(int i, int j) {
        System.out.println("the method div begin whith ["+i+","+j+"]");
        int result=i/j;
        System.out.println("the method div end whith"+result);
        return result;
    
    }

}
View Code

 

技术分享图片
package com.tanlei.spring.bean.Aop;

public class Main {
   public static void main(String[] args) {
    AtithmeticCalculatorImpl  aImpl=new AtithmeticCalculatorImpl();
    aImpl.add(4, 8);
    aImpl.sub(4, 8);
    aImpl.mul(4, 8);
    aImpl.div(4, 8);
}
}
View Code

 

1.执行方法前后的日志

   代码混乱

 代码分散

使用动态代理解决上述问题

 复杂动态代理代码(不推荐使用)

package com.tanlei.spring.bean.Aop;

public interface AtithmeticCalculator {
    int add(int i,int j);
    int sub(int i,int j);
    int mul(int i,int j);
    int div(int i,int j);
}

 

package com.tanlei.spring.bean.Aop;

public class AtithmeticCalculatorImpl implements AtithmeticCalculator{

    @Override
    public int add(int i, int j) {
        int result=i+j;
        return result;
    }

    @Override
    public int sub(int i, int j) {
        int result=i-j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result=i*j;
        return result;
        
    }

    @Override
    public int div(int i, int j) {
        int result=i/j;
        return result;
    
    }

}

 

package com.tanlei.spring.bean.Aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class AtithmeticCalculatorLoggingProxy {

    // 要代理的对象
    private AtithmeticCalculator target;

    public AtithmeticCalculatorLoggingProxy(AtithmeticCalculator target) {
        this.target = target;
    }

    
    public AtithmeticCalculator getLoggingProxy() {
        AtithmeticCalculator proxy = null;

        // 代理对象由哪一个类加载器负责
        ClassLoader loader = target.getClass().getClassLoader();
        // 代理对象的类型,即其中有哪些方法
        Class[] interfaces = new Class[] { AtithmeticCalculator.class };

        // 当调用代理对象其中的方法时,该执行的代码
        InvocationHandler h = new InvocationHandler() {
            /**
             * proxy:正在返回的那个代理对象,一般情况下,在invoke方法中都不使用该对象
             * method:正在被调用的方法
             * args:调用方法时传人的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String methodName=method.getName();
                //日志
                System.out.println("The method: "+methodName+"begins with"+Arrays.asList(args));
                //执行方法
                Object result=method.invoke(target, args);
                
                //日志
                System.out.println("The method: "+methodName+"ends with"+result);
                return result;
            }
        };
        proxy = (AtithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
        return proxy;
    }
}

 

package com.tanlei.spring.bean.Aop;

public class Main {
   public static void main(String[] args) {
    /*AtithmeticCalculatorLoggingImpl  aImpl=new AtithmeticCalculatorLoggingImpl();
    aImpl.add(4, 8);
    aImpl.sub(4, 8);
    aImpl.mul(4, 8);
    aImpl.div(4, 8);*/
       AtithmeticCalculator target=new AtithmeticCalculatorImpl();
       AtithmeticCalculator proxy=new AtithmeticCalculatorLoggingProxy(target).getLoggingProxy();
       int result=proxy.add(1, 2);
       System.out.println(result);
}
}

 

简单的方法实现动态代理(AOP)

AOP基本概念

   面向切面编程

在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类,这样一来横切关注点就被模块化到特殊的对象(切面)里;

Aop的好处

  每个事物处理逻辑位于一个位置,代码不分散,便于维护和升级

  业务模块更简洁,只包含核心业务代码

 

Spring AOP+AspectJ注解

AspectJ:java社区里最完整最流行的AOP框架

  在Spring2.0版本上,可以使用基于AspectJ注解基于XML配置AOP

在Spring中启用AspectJ注解支持

1.导入jar包:

  aopalliance-.jar

  aspectj.weaver.jar

  spring-aspects.jar

2.要在Spring Ioc容器中启用AspectJ注解支持,只要在bean配置文件中定义一个空的XML元素<aop:aspectj-autoproxy>

3.当Spring IOC容器侦测到Bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为AspectJ切面匹配的Bean创建代理

常见AspectJ的注解:
  1. @Before – 方法执行前运行
  2. @After – 运行在方法返回结果后
  3. @AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。
  4. @AfterThrowing – 运行方法在抛出异常后,
  5. @Around – 围绕方法执行运行,结合以上这三个通知。 

小结: 

1.Spring AOP

1).加入jar包
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar

commons-logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

2).配置文件中加入Aop的命名空间

3)基于注解的方式
1.在配置文件中加入如下配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.把横切关注点的代码抽象到切面的类中
    切面首先是一个IOC的bean,即加入@Componet注解
    切面还需要加入@Aspect 注解

3.类中声明各种通知
@Before – 方法执行前运行
@After – 运行在方法返回结果后
@AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。
@AfterThrowing – 运行方法在抛出异常后,
@Around – 围绕方法执行运行,结合以上这三个通知。
1.声明一个方法  
2.在方法前加入@Before
3.在通知的方法里面可以加入连接点JoinPoint  访问方法的参数  如方法的签名和参数

 

Spring AOP前置 通知

技术分享图片

 

 

 

 

 

注意点:

对于Spring AOP 采用两种代理方法,一种是常规JDK,一种是CGLIB,我的UserDaoImpl实现了一个接口IUserDao,当代理对象实现了至少一个接口时,默认使用JDK动态创建代理对象,当代理对象没有实现任何接口时,就会使用CGLIB方法。由于UserDAOImpl实现了UserDAO接口,所以强制转换必须用父类UserDAO来定义

如果你的代理对象没有实现接口的方法,就将代理对象转换成接口。 
  获取代理类的代码该为: 

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDaoImpl)ctx.getBean("userDaoImpl");

 

Spring_Aop

标签:流行   span   抽象   void   logging   div   cat   4.0   com   

原文地址:https://www.cnblogs.com/tanlei-sxs/p/10140920.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!