zoukankan      html  css  js  c++  java
  • Spring---Aop

    Spring Aop介绍:
    
    1.Aop介绍
        Spring Aop是面向切面编程,底层是动态代理。可以实现在不改变源码的情况下,对目标方法进行增强。
    Spring Aop支持声明式事务,与编程式事务相比较,声明式事务最大的优点就是不需要通过编程的方式管
    理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过
    基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
        
        Spring Aop的典型使用场景:
            1.事务管理;
            2.日志记录;
            3.权限控制
    
    2.Spring Aop术语:
            JoinPoint: 连接点:
                所有的方法都可以是连接点;
            Pointcut: 切入点:
                需要进行增强的方法就是切入点;
            Advice: 通知/增强 :
                增强的逻辑就是通知,通知需要切入到切入点中;
                通知分为:
                    前置通知;
                    后置通知;
                    环绕通知;
                    异常通知;
                    最终通知;
            Aspect: 切面:
                切入点和通知的结合就是切面;
                
    3.Aop的使用:
        1.创建工程,导入坐标依赖:
            <?xml version="1.0" encoding="UTF-8"?>
            <project xmlns="http://maven.apache.org/POM/4.0.0"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                <modelVersion>4.0.0</modelVersion>
    
                <groupId>com.it</groupId>
                <artifactId>spring-aop</artifactId>
                <version>1.0-SNAPSHOT</version>
    
    
                <dependencies>
                    <!--Spring核心容器-->
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-context</artifactId>
                        <version>5.0.2.RELEASE</version>
                    </dependency>
                    <!--SpringAOP相关的坐标-->
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjweaver</artifactId>
                        <version>1.8.7</version>
                    </dependency>
    
                    <!--Spring整合单元测试-->
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-test</artifactId>
                        <version>5.0.2.RELEASE</version>
                    </dependency>
                    <!--单元测试-->
                    <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>4.12</version>
                        <scope>test</scope>
                    </dependency>
                </dependencies>
    
    
            </project>
        
        2.创建Dao接口,定义方法;
            public interface AccountDao {
    
                void save();
    
                Object delete();
    
                void findAll();
    
                void update();
    
                void findById();
            }
            
        3.创建Dao接口的实现类,重写接口方法(在这里,这些方法就是需要进行增强的方法)
            public class AccountDaoImpl implements AccountDao {
                public void save() {
                    System.out.println("save....");
                }
    
                public Object delete() {
                    System.out.println("delete....");
                    return "success";
                }
    
                public void findAll() {
                    //模拟耗时
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("findAll...");
                }
    
                public void update() {
                    System.out.println("update....");
                    int i=1/0;
                }
    
                public void findById() {
                    System.out.println("findById.....");
                    int i=1/0;
                }
            }
            
        4.创建切面类,类中定义增强逻辑方法:
            public class MyAspect {
    
                //前置通知,增强逻辑
                public void check(){
                    System.out.println("权限校验。。。");
                }
                //后置通知,增强逻辑
                public void log(Object obj){
                    System.out.println("日志记录。。。"+obj);
                }
                //环绕通知,增强逻辑
                public void showTime(ProceedingJoinPoint joinPoint) throws Throwable {
                    //目标方法调用之前
                    System.out.println("调用之前的时间:"+System.currentTimeMillis());
                    //调用目标方法
                    joinPoint.proceed();
                    //目标方法调用之后
                    System.out.println("调用之后的时间:"+System.currentTimeMillis());
    
                }
                //异常通知,增强逻辑
                public void throwException(Exception e){
                    System.out.println("异常抛出通知========"+e.getMessage());
                }
    
                //最终通知,增强逻辑
                public void showFinal(){
                    System.out.println("最终通知。。。");
                }
    
            }
            
        5.配置文件:
            在配置文件中注册Dao实现类和切面类;
            在配置文件中配置aop,在aop中配置切入点和切面,在切面中配置通知;
            
            <?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"
                   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">
                <!--注册Dao-->
                <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"></bean>
                <!--注册增强类-->
                <bean id="myAspect" class="com.it.aspect.MyAspect"></bean>
    
                <!--配置aop-->
                <aop:config>
                    <!--配置切入点,目的是找到需要进行增强的方法-->
                    <!--
                        expression:表达式:
                        execution():固定写法
                        第一个 * 号:表示任意的返回值;
                        第二个 * 号:表示包名com.it.aspect下的任意类
                        第三个 * 号:表示任意方法
                        (..):表示方法的任意参数
                    -->
                    <aop:pointcut id="point01" expression="execution(* com.it.dao.impl.AccountDaoImpl.save(..))"></aop:pointcut>
                    <aop:pointcut id="point02" expression="execution(* com.it.dao.impl.AccountDaoImpl.delete(..))"></aop:pointcut>
                    <aop:pointcut id="point03" expression="execution(* com.it.dao.impl.AccountDaoImpl.findAll(..))"></aop:pointcut>
                    <aop:pointcut id="point04" expression="execution(* com.it.dao.impl.AccountDaoImpl.update(..))"></aop:pointcut>
                    <aop:pointcut id="point05" expression="execution(* com.it.dao.impl.AccountDaoImpl.findById(..))"></aop:pointcut>
                    <!--配置切面,找到对应的增强类-->
                    <aop:aspect ref="myAspect">
                        <!--配置前置通知,将增强类的增强逻辑切入到被增强的方法中-->
                        <aop:before method="check" pointcut-ref="point01"></aop:before>
                        <!--后置通知,可以获得目标方法返回参数-->
                        <aop:after-returning method="log" pointcut-ref="point02" returning="obj"></aop:after-returning>
                        <!--配置环绕通知-->
                        <aop:around method="showTime" pointcut-ref="point03"></aop:around>
                        <!--配置异常通知,可以获取异常信息-->
                        <aop:after-throwing method="throwException" pointcut-ref="point04" throwing="e"></aop:after-throwing>
                        <!--最终通知-->
                        <aop:after method="showFinal" pointcut-ref="point05"></aop:after>
                    </aop:aspect>
    
    
                </aop:config>
            </beans>
            
        6.编写测试:
            RunWith(SpringJUnit4ClassRunner.class)
            @ContextConfiguration(value = "classpath:applicationContext.xml")
            public class Test {
    
                @Autowired
                private AccountDao accountDao;
    
                @org.junit.Test
                public void fun(){
                    accountDao.save();
                }
    
                @org.junit.Test
                public void fun02(){
                    accountDao.delete();
                }
    
                @org.junit.Test
                public void fun03(){
                    accountDao.findAll();
                }
    
                //测试异常通知
                @org.junit.Test
                public void fun04(){
                    accountDao.update();
                }
    
                //测试最终通知
                @org.junit.Test
                public void fun05(){
                    accountDao.findById();
                }
    
    
            }
    
            
        
            
                
  • 相关阅读:
    PAT顶级 1024 Currency Exchange Centers (35分)(最小生成树)
    Codeforces 1282B2 K for the Price of One (Hard Version)
    1023 Have Fun with Numbers (20)
    1005 Spell It Right (20)
    1092 To Buy or Not to Buy (20)
    1118 Birds in Forest (25)
    1130 Infix Expression (25)
    1085 Perfect Sequence (25)
    1109 Group Photo (25)
    1073 Scientific Notation (20)
  • 原文地址:https://www.cnblogs.com/lyle-liu/p/12774173.html
Copyright © 2011-2022 走看看