zoukankan      html  css  js  c++  java
  • Spring_面向切面术语讲解/AOP

    1.切面:例如银行系统,先检测是否安全,再执行核心(业务)层,再记录日志,再清空缓存记录,除了核心层都是切面

    2.通知:切面里的方法叫通知

      前置通知:是在核心(业务)类前面执行的就是前置通知

      后置通知:是在核心(业务)类后面执行的就是前置通知

      环绕通知:

      异常通知:

    3.连接点:核心类(目标业务方法)就是接入点

    4.织入:将目标业务方法、通知等连接起来的过程

    5.代理: 代理类将所有切面写到一起

    AOP

    将三个jar包复制到src下的lib中,并build path - add to build path

    aspectjrt.jar

    aspectjweaver.jar

    cglib-nodep-2.1_3.jar

    在主xml中(applicationContext.xml)中写<aop>是有提示的,如果没有就是要配模板,也就是上面那个网址一样的东西。之所以<bean>有提示是因为上面配置了http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

    1.配置aop提示模板:

      文件:spring-aop-2.5.xsd

    需要主配置文件和局部配置文件的上面的链接改为:

    <?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-2.5.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
            
    
    </beans>

    Eclipse的window - Preferences - XML Catalog - Add

    将spring-aop-2.5.xsd的路径放进去,Key里放入http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  Ket type选第二个。ok

    配置成功后输<aop就会有提示

    2.配置切入点和切面

    <?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-2.5.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
            <!-- 配置安全bean -->
            <bean id="security" class = "cn.java.aop.Security"></bean>
            <!-- 配置核心业务bean -->
            <bean id="bankServiceImpl" class = "cn.java.aop.BankServiceImpl"></bean>
            <!-- 配置日志bean -->
            <bean id="log" class = "cn.java.aop.Log"></bean>
            <!-- 配置清空缓存bean -->
            <bean id="clean" class = "cn.java.aop.Clean"></bean>
    
            <!-- 配置aop -->
            <aop:config>
                <!-- 配置切点
                 .*代表这个类下的所有方法 。后面的..代表有参和无参的所有方法-->
                <aop:pointcut expression="execution (* cn.java.aop.BankServiceImpl.*(..))" id="abc"/>
                
                <!-- 配置切面 
                    ref:上面需要配置切面的bean的id
                    aop:before 代表前置通知
                    method:通知方法名
                    pointcut-ref:在哪个切入点前执行,内容为切入点的bean的id
                    aop:after 后置通知
                    order:配置后置通知的执行顺序,数值越大越先执行
                -->
                <aop:aspect ref="security">
                    <aop:before method="isSecurity" pointcut-ref="abc" />
                </aop:aspect>
                
                <aop:aspect ref="log" order="2" >
                    <aop:after method="record" pointcut-ref="abc" />
                </aop:aspect>
                <aop:aspect ref="clean" order="1">
                    <aop:after method="qingKong" pointcut-ref="abc" />
                </aop:aspect>
            </aop:config>
            
    
    </beans>

    配置能接收返回值的后置通知

    package cn.java.aop;
    
    public class Receive {
        public void printMoney(int m){
            System.out.println("余额为:" + m + "");
        }
    }
                <!-- 
                接受返回值,如果没有返回值就不调用
                ref:要接受参数的那个类 
                method:类中要接受参数的那个方法
                pointcut-ref:切点
                returning:方法中要接收参数的那个参数
                -->
                <aop:aspect ref="receive"> 
                    <aop:after-returning method="printMoney" pointcut-ref="abc" returning="m"/>
                </aop:aspect>

    环绕通知

    验证用户名密码

    package cn.java.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class Auth {
        private String username = "wang";
        private String password = "123";
        public void userExist(ProceedingJoinPoint p) throws Throwable {
            
            if ("admin".equals(username) && "123".equals(password)) {
                //放行。继续往程序后面走
                p.proceed();
            }else {
                //没写p.proceed();就是不放行,程序不继续走
                System.out.println("用户名或密码错误");
            }
        }
    }
                <!-- 
                配置环绕通知
                ref:bean的id
                method:类中方法名
                pointcut-ref:切点
                 -->
                <aop:aspect ref="auth">
                    <aop:around method="userExist" pointcut-ref="abc"/>
                </aop:aspect>
                
    重点:ProceedingJoinPoint 是spring中的

    异常通知

    出错的时候不能显示给用户404 500页面,异常都捕获到一个类中

    新建类名Global,方法叫handExpt()。再给这个类配置个bean

     

    package cn.java.aop;
    
    public class Global {
        public void handExpt(Throwable ex) {
            System.out.println("出错了");//真实项目这里是要跳转到一个页面的
        }
    }
                <!-- 
                异常通知,当业务方法发生错误的时候才会被调用
                throwing:值为接受异常的那个类中方法要接收的参数public void handExpt(Throwable ex) {System.out.println("出错了");}
                -->
                <aop:aspect ref="global">
                    <aop:after-throwing method="handExpt" pointcut-ref="abc" throwing="ex"/>
                </aop:aspect> 
  • 相关阅读:
    PAT (Advanced Level) Practice 1054 The Dominant Color (20 分)
    PAT (Advanced Level) Practice 1005 Spell It Right (20 分) (switch)
    PAT (Advanced Level) Practice 1006 Sign In and Sign Out (25 分) (排序)
    hdu 5114 Collision
    hdu4365 Palindrome graph
    单链表查找最大值、两个递增的链表合并并且去重
    蓝桥杯-最短路 (SPFA算法学习)
    蓝桥杯-最大最小公倍数
    Codeforces-470 div2 C题
    蓝桥杯-地宫取宝
  • 原文地址:https://www.cnblogs.com/lonske/p/9061366.html
Copyright © 2011-2022 走看看