Spring --13.Spring中AOP编程(注解方式)

版权声明:转载请注明原始链接 https://blog.csdn.net/sswqzx/article/details/83989557

1、基于注解AOP入门案例

1.2、创建工程引入依赖

pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
    </dependencies>

1.3、编写Spring配置文件

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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启Spring注解扫描-->
    <context:component-scan base-package="com.day03"> </context:component-scan>
    <!--开启aspectj自动代理-->
    <aop:aspectj-autoproxy> </aop:aspectj-autoproxy>

</beans>

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout, file

1.4、创建接口和实现类

UserDao.java

package com.day03.dao;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
public interface UserDao {
    public abstract void save();
    public abstract Integer delete();
    public abstract Integer update(int a, int b);
    public abstract void list();
}

UserDaoImpl.java

package com.day03.dao.Impl;

import com.day03.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
@Repository("userDao")
public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("save方法。。。。。。。。。。。");
    }

    @Override
    public Integer delete() {
        System.out.println("delete方法。。。。。。。。。。。");
        return 100;
    }

    @Override
    public Integer update(int a, int b) {
        System.out.println("update......................");
        int c = a + b;
        return c;
    }

    @Override
    public void list() {
        //int a = 10/0;
        System.out.println("List...........................");
    }
}

1.5、编写切面类

MyAspectAnno.java

package com.day03.aspect;

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

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 9:30 2018/11/13
 */
@Component
@Aspect //表示该类是一个切面类
public class MyAspectAnno {
}

1.6、编写测试类

MyTestAnno.java

package com.day03.test;

import com.day03.dao.UserDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 9:32 2018/11/13
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class MyTestAnno {

    @Autowired
    private UserDao userDao;

    //前置通知
    @Test
    public void tes1(){
        userDao.save();
    }

    //后置通知
    @Test
    public void test2(){
        userDao.delete();
    }

    //环绕通知
    @Test
    public void test3(){
        userDao.update(5,10);
    }
    //异常通知
    @Test
    public void test4(){
        userDao.list();
    }
}

2、用注解来配置各种通知

前置通知、后置通知、环绕通知、异常通知、最终通知

MyAspectAnno.java切面类

package com.day03.aspect;

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

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 9:30 2018/11/13
 */
@Component
@Aspect //表示该类是一个切面类
public class MyAspectAnno {

    /**
     * 前置通知方法 应用场景: 权限控制 (权限不足,抛出异常)、 记录方法调用信息日志 joinPoint:连接点,指的是被增强的那个方法
     * @param jp
     */
    @Before("execution(* com.day03.dao.Impl.UserDaoImpl.save(..))")
    public void before(JoinPoint jp){
        String username = "admin";
        if (!"user".equals(username)){
            throw new RuntimeException("你没有对类"+jp.getTarget().getClass().getName()+"中的方法"+jp.getSignature().getName()+"访问权限!");
        }
    }

    /**
     * 后置通知方法 应用场景: ATM取款机取款后,自动下发短信 参数result:被增强那个方法的返回值
     *     returning属性指定目标方法返回值的名字
     */
    @AfterReturning(value = "execution(* com.day03.dao.Impl.UserDaoImpl.delete(..))",returning = "result")
    public void afterRunnings(JoinPoint jp,Object result){

        System.out.println("你在ATM机上取了:"+result+"元");
    }


     /**
     * 环绕通知方法 应用场景:事务处理
     * proceedingJoinPoint
     *  正在执行的连接点
     * @return
     */
    @Around("execution(* com.day03.dao.Impl.UserDaoImpl.update(..))")
    public Object around(ProceedingJoinPoint pjp){
        System.out.println("开启事务");
        Object[] args = pjp.getArgs();//获取参数
        Object proceed = null;
        try {
            proceed = pjp.proceed(args);
//            int a = 10/0;
            System.out.println("proceed = " + proceed);
            System.out.println("提交事务");
        } catch (Throwable throwable) {
            System.out.println("回滚事务");
        }

        return proceed;
    }


    /**
     * 异常通知方法、应用:异常处理
     * @param ex
     * 目标方法抛出的异常
     */
    @AfterThrowing(value = "execution(* com.day03.dao.Impl.UserDaoImpl.list(..))",throwing = "ex")
    public void afterThroing(JoinPoint jp , Throwable ex){
        throw  new RuntimeException("在这个类:"+jp.getTarget().getClass().getName()+"中的方法"+jp.getSignature().getName()+"抛出异常"+ex.getMessage());
    }

    /**
     *最终通知方法 应用场景:释放资源 (关闭文件、 关闭数据库连接、 网络连接、 释放内存对象 )
     *@param joinPoint  被增强的那个方法
     */
    @After("execution(* com.day03.dao.Impl.UserDaoImpl.list(..))")
    public void after(JoinPoint joinPoint){
        System.out.println("释放资源、对应的类为"+joinPoint.getTarget().getClass().getName()+"方法为:"+joinPoint.getSignature().getName());
    }

}

UserDaoImpl.java

package com.day03.dao.Impl;

import com.day03.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
@Repository("userDao")
public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("save方法。。。。。。。。。。。");
    }

    @Override
    public Integer delete() {
        System.out.println("delete方法。。。。。。。。。。。");
        return 100;
    }

    @Override
    public Integer update(int a, int b) {
        System.out.println("update......................");
        int c = a + b;
        return c;
    }

    @Override
    public void list() {
        //int a = 10/0;
        System.out.println("List...........................");
    }
}

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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启Spring注解扫描-->
    <context:component-scan base-package="com.day03"> </context:component-scan>
    <!--开启aspectj自动代理-->
    <aop:aspectj-autoproxy> </aop:aspectj-autoproxy>

</beans>

MyTestAnno.java

package com.day03.test;

import com.day03.dao.UserDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 9:32 2018/11/13
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class MyTestAnno {

    @Autowired
    private UserDao userDao;

    //前置通知
    @Test
    public void tes1(){
        userDao.save();
    }

    //后置通知
    @Test
    public void test2(){
        userDao.delete();
    }

    //环绕通知
    @Test
    public void test3(){
        userDao.update(5,10);
    }
    //异常通知
    @Test
    public void test4(){
        userDao.list();
    }
}

猜你喜欢

转载自blog.csdn.net/sswqzx/article/details/83989557