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> 

 

posted on 2018-05-19 19:24  lonske  阅读(297)  评论(0编辑  收藏  举报