Spring-aop面向切面编程笔记

1.需要引入的jar包

AOP功能是基于IOC的功能之上,所有需要先引入ioc的全部jar包

AOP和ASPECTS是构成AOP的基础,所有需引入这两个jar包

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.25.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.25.RELEASE</version>
    </dependency>

 2.名词解释

切入点:重复的代码,被加在其他方法前后的代码

切面:任何一个类,里面有多个切入点

关注点:目标,要加到哪里去,可以是一个方法、一个类的所有方法、一个包下的所有类

com.blb.Run.*(..)) 一个类的所有方法
execution(* com.blb..*(..)) 包下任意层

3.常用注释

@Aspect 把该类声明为切面

@Before :把方法在目标前执行

      @Before("execution(* com.blb.Run.*(..))") 指定关注点

@After:同@Before

@AfterReturning:方法正常完成后执行

@AfterThrowing: 抛出增强(目标方法发生异常,执行)

@Around: 环绕增强(目标方法执行前后,分别执行一些代码)

@Pointcut:定义一个公用的切面表达式,其他方法只需用它修饰的方法名即可代替切面表达式

@Pointcut("execution(* com.blb.UserDao.*(..))")
    public void xiaohong(){
        System.out.println("hello");
    }
@After(
"xiaohong()") public void go(){ System.out.println("hou1"); } @After("xiaohong()") public void go2(){ System.out.println("hou2"); }

4.配置文件使用

引入的jar包只能用xml配置文件的方式加入ioc容器

使用aop切片也一样用到xml文件

aop:pointcut:是定义一个公用的pointcut(写目标位置)
<!--    加入到ioc容器-->
    <bean id="hang" class="com.blb.Hang"></bean>
    <aop:config>
        <aop:aspect ref="hang">
            <aop:pointcut id="xiaobai" expression="execution(* com.blb.UserDao.*(..))"/>
            <aop:before method="sayHello" pointcut-ref="xiaobai"></aop:before>
            <aop:after method="sayHello" pointcut="execution(* com.blb.UserDao.*(..))"/>
        </aop:aspect>
    </aop:config>
1. <aop:config>  作用:声明aop配置

2. <aop:pointcut> 作用:配置切入点表达式   属性:id:唯一标识切入点表达式名称 expression:定义切入点表达式

3. <aop:aspect> 作用:配置切面  属性:id:唯一标识切面的名称  ref:引用切面类(通知类)bean的id

4. <aop:before> 作用:配置前置通知(在执行目标对象方法之前执行) 属性:method:指定通知方法名称 pointcut:定义切入点表达式  pointcut-ref:引用切入点表达式的id。

5.<aop:returning> 作用:配置后置通知 属性:method:指定通知方法名称 pointcut:定义切入点表达式 point-ref:引用切入点表达式的id

6.<aop:after-throwing> 作用:配置异常通知  属性:method:指定通知方法名称  pointcut:定义切入点表达式  pointcut-ref:引用切入点表达式的id

7.<aop:after> 作用:配置最终通知 属性:method:指定通知方法名称  pointcut:定义切入点表达式  pointcut-ref:引用切入点表达式的id

8. <aop:around> 作用:配置环绕通知 属性:method:指定通知方法名称  pointcut:定义切入点表达式  pointcut-ref:引用切入点表达式的id

5.代码使用

applicationContext.xml文件:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
">
<!--启用注解-->
    <context:annotation-config></context:annotation-config>
<!--设置扫描范围-->
    <context:component-scan base-package="com.blb"></context:component-scan>
<!--启用aop功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

log4j.properties:

log4j.rootLogger=INFO,Log4jConsole

log4j.appender.Log4jConsole=org.apache.log4j.ConsoleAppender
log4j.appender.Log4jConsole.Threshold=INFO
log4j.appender.Log4jConsole.ImmediateFlush=true
log4j.appender.Log4jConsole.Target=System.out

log4j.appender.Log4jConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.Log4jConsole.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss,SSS}]

切面类:

package com.blb;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.logging.Logger;


@Component //加到ioc
@Aspect  //切面
public class Haha {
    private Logger logger= Logger.getLogger(String.valueOf(Haha.class));
@Before("execution(* com.blb.Run.*(..))")
    public void before(){
        System.out.println("begin");
    }
@After("execution(* com.blb.Run.*(..))")
    public void after(){
        System.out.println("end");
    }
    @AfterThrowing("execution(* com.blb.Run.*(..))")
    public void exprission(){
        System.out.println("你的代码发生了异常");
    }

@Around("execution(* com.blb.Mark.*(..))")
    public void around(ProceedingJoinPoint point){
    logger.info(point.getSignature().getName()+"--------start");//获取类名

    try {
        point.proceed();  //表示注入点方法
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }

    logger.info(point.getSignature().getName()+"--------end");

}
}

注入点:

package com.blb;

import org.springframework.stereotype.Component;

@Component
public class Run {
   public void hello()
   {
       System.out.println("nigao!");
   }
}

测试代码:

package com.blb;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {
@Test
    public void getAOP(){
        BeanFactory bf=new ClassPathXmlApplicationContext("applicationContext.xml");
        Run run = (Run)bf.getBean("run");
        run.hello();
    }

    @Test
    public void getMark(){
        BeanFactory bf=new ClassPathXmlApplicationContext("applicationContext.xml");
        Mark mark=(Mark) bf.getBean("mark");
        mark.say();
    }
}
原文地址:https://www.cnblogs.com/asksk/p/12683709.html