加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

spring-aop学习【基于注解】

发布时间:2020-12-15 01:10:55 所属栏目:大数据 来源:网络整理
导读:我个人觉得,这个好像就是用在定制日志输出上,和log4j很像。 用途: 如果业务方法调用每一步都需要详细的日志,那就用这个吧 好处就是: 方便维护,只包含业务代码 下面开始说明: 所需要的jar包: com.springsource.net.sf.cglib-2.2.0.jar com.springsour

我个人觉得,这个好像就是用在定制日志输出上,和log4j很像。

用途:

如果业务方法调用每一步都需要详细的日志,那就用这个吧

好处就是:

方便维护,只包含业务代码

下面开始说明:

所需要的jar包:

com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.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

直接上代码:

声明一个接口

package com.spring.bean.aop;

import java.util.List;

/**
 * 
 * @author Administrator
 *
 */
public interface UserService {
//    打招呼
    void say();
    获取年龄
    int getValue(List<Integer> array,int index);
}

这是接口的实现类

 org.springframework.beans.factory.annotation.Autowired;
 org.springframework.stereotype.Service;

 Administrator
 *      实现类
 */
@Service("userService")
class UserServiceImpl implements UserService {

    
     * 自动装配use对象
     
    @Autowired
    private User user;
    @Override
     say() {
         TODO Auto-generated method stub
        System.out.println("我叫"+user.getName()+",今年"+user.getAge()+"岁,你好!!");
    }
    
    @Override
     index) {
         TODO Auto-generated method stub
        return array.get(index);
    }


}

用户对象信息

 org.springframework.stereotype.Component;


 *  Administrator
 *      用户信息
 
@Component
class User {

    String name;
     age;
    public String getName() {
         name;
    }
     setName(String name) {
        this.name = getAge() {
         age;
    }
    void setAge( age) {
        this.age = age;
    }
}

然后是两个切面代码

 java.util.Arrays;

 org.aspectj.lang.JoinPoint;
 org.aspectj.lang.ProceedingJoinPoint;
 org.aspectj.lang.annotation.After;
 org.aspectj.lang.annotation.AfterReturning;
 org.aspectj.lang.annotation.AfterThrowing;
 org.aspectj.lang.annotation.Around;
 org.aspectj.lang.annotation.Aspect;
 org.aspectj.lang.annotation.Before;
 org.aspectj.lang.annotation.Pointcut;
 org.springframework.core.annotation.Order;

 * 声明一个切面
 * */
//order可以指定哪个切面先执行,数值越小,优先执行
@Order(1) @Aspect @Component MyLoggingAspectj { 声明一个切入点 @Pointcut("execution(* *(..))") pointcut(){ } * 前置通知,该方法执行在被调用方法之前 * @param joinPoint @Before("pointcut())" beforeMethod(JoinPoint joinPoint){ 获得调用的方法名 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); System.out.println("MyLoggingAspectj the method "+methodName+"begins with "+Arrays.asList(args)); } }
第二个切面代码

@Order(2 LoggingAspectj {
    
    
 pointcut(){
        
    }

/*    *//***//*
    @Before("pointcut())")
    public void beforeMethod(JoinPoint joinPoint){
//        获得调用的方法名
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("the method "+methodName+"begins with "+Arrays.asList(args));
    }
    
    
     * 后置通知
     * 该方法执行在被调用方法之后,报错也依然执行
     * 
    @After("pointcut())")
    public void afterMethod(JoinPoint joinPoint){
//        获得调用的方法名
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("the method "+methodName+"Ends with "+Arrays.asList(args));
    }
    
    
     * 返回通知,在方法返回结果之后执行,异常无返回值
     * 
    @AfterReturning(value="pointcut())",returning="result")
    public void afterReturning(JoinPoint joinPoint,Object result){
//        获得调用的方法名
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("the method "+methodName+"afterReturning with "+Arrays.asList(args)+"  ["+result+"]");
    }
    
    
     * 异常通知
     * 在方法抛出异常之后
     * 
    @AfterThrowing(value="pointcut()",throwing="e")
    public void afterReturning(JoinPoint joinPoint,Exception e){
//        获得调用的方法名
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("the method "+methodName+"afterThrowing with "+Arrays.asList(args)+e);
    }*/
    
    
     * 环绕通知需要配合ProceedingJoinPoint使用,相当于动态代理
     *  pjp
     * @return
     
    @Around(value="pointcut()" Object aroundMethod(ProceedingJoinPoint pjp) {
         获得调用的方法名
        String methodName = pjp.getSignature().getName();
        Object result = null;
         调用目标方法
        try {
             前置通知
            System.out.println("the method " + methodName + "Begins with " + Arrays.asList(pjp.getArgs()));
            result = pjp.proceed();
             后置通知
            System.out.println("the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()));
             后置有返回值
            System.out.println(
                    "the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()) + " [" + result + "]");
        } catch (Throwable e) {
             TODO Auto-generated catch block
             异常通知
            System.out.println("the method " + methodName + "AfterThrowing with " + Arrays.asList(pjp.getArgs()) + e);
             e.printStackTrace();
             不加这句,会报错,因为result返回值为null
            throw new RuntimeException(e);
        }
        System.out.println("the method " + methodName + "LastEnds with " + Arrays.asList(pjp.getArgs()));
         result;
    }
    
    
}

测试代码:

 java.util.ArrayList;
 org.springframework.context.ApplicationContext;
 org.springframework.context.support.ClassPathXmlApplicationContext;

 Main {

    static  main(String[] args) {
         TODO Auto-generated method stub
        ApplicationContext ctx=new ClassPathXmlApplicationContext("bean-aop.xml");
        UserService userServiceImpl=(UserService) ctx.getBean("userService");
        User user=(User) ctx.getBean("user");
        List<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(1);
        arrayList.add(2);
        int age = userServiceImpl.getValue(arrayList,1);
        user.setName("xiaoqiang");
        user.setAge(age);
        userServiceImpl.say();
    }

}

bean文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 自动扫描的包 -->
    context:component-scan base-package="com.spring.bean.aop"></context:component-scan 使 AspectJ 的注解起作用 aop:aspectj-autoproxy>

</beans>

?

?总结:
1.在pom文件添加依赖,在 Spring 的配置文件中加入 aop 的命名空间。?
    使用AspectJ方式注解需要相应的包-->  
         dependency>  
            groupId>org.aspectjartifactId>aspectjrtversion>${aspectj.version}>  
        >  
         -->  
        >aspectjweaver> 

2.为接口实现类添加注解@Component

3.编写一个切面类,配置切面

* 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.spring.bean.aop"></context:component-scan>

* 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
* 为匹配的类自动生成动态代理对象.

4.编写前置通知方法,在方法上方添加注解

// 表达式注意格式: 修饰 +方法(有无返回)+包名+类名+方法名+参数


? @Before("execution(public int com.spring.bean.annotation.aopimpl.Calculation.sub(int,int))")

* @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体.
* @Before 里面的是切入点表达式:

如关注详细参数,添加joinpoint对象,可以访问到方法的签名和参数

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读