Spring之Aop练习

来源:互联网 发布:linux怎么移动文件夹 编辑:程序博客网 时间:2024/05/16 18:40

注意一下,在讲解之前,说明一点:使用Spring AOP,要成功运行起代码,只用Spring提供给开发者的jar包是不够的,请额外上网下载两个jar包:

1、aopalliance.jar

2、aspectjweaver.jar

开始讲解用Spring AOP的XML实现方式,先定义一个接口:

package cn.itcast.oa.service;public interface HelloWorld {    void printHelloWorld();    void doPrint();}

两个实现类:

package cn.itcast.oa.service.impl;import cn.itcast.oa.service.HelloWorld;public class HelloWorldImpl1 implements HelloWorld {    public void printHelloWorld() {        System.out.println("Enter HelloWorldImpl1.printHelloWorld()");    }    public void doPrint() {        System.out.println("Enter HelloWorldImpl1.doPrint()");        return;    }}
package cn.itcast.oa.service.impl;import cn.itcast.oa.service.HelloWorld;public class HelloWorldImpl2 implements HelloWorld {    public void printHelloWorld() {        System.out.println("Enter HelloWorldImpl2.printHelloWorld()");    }    public void doPrint() {        System.out.println("Enter HelloWorldImpl2.doPrint()");        return;    }}

横切关注点,这里面是打印时间:

package cn.itcast.oa.service.impl;public class TimeHandler {    public void printTime() {        System.out.println("CurrentTime = " + System.currentTimeMillis());    }}

测试代码:

package cn.itcast.oa.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.oa.service.HelloWorld;public class TestAop {    public static void main(String[] args) {        ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");        HelloWorld hw1 = (HelloWorld) ctx.getBean("helloWorldImpl1");        HelloWorld hw2 = (HelloWorld) ctx.getBean("helloWorldImpl2");        hw1.printHelloWorld();        System.out.println();        hw1.doPrint();        System.out.println();        hw2.printHelloWorld();        System.out.println();        hw2.doPrint();    }}

新建aop.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:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">    <bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />    <bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />    <bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />    <aop:config>        <aop:aspect id="time" ref="timeHandler">            <aop:pointcut id="addAllMethod"                expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />            <aop:before method="printTime" pointcut-ref="addAllMethod" />            <aop:after method="printTime" pointcut-ref="addAllMethod" />        </aop:aspect>    </aop:config></beans>

实验结果:

CurrentTime = 1482635730488Enter HelloWorldImpl1.printHelloWorld()CurrentTime = 1482635730489CurrentTime = 1482635730491Enter HelloWorldImpl1.doPrint()CurrentTime = 1482635730491CurrentTime = 1482635730491Enter HelloWorldImpl2.printHelloWorld()CurrentTime = 1482635730491CurrentTime = 1482635730491Enter HelloWorldImpl2.doPrint()CurrentTime = 1482635730491

基于Spring的AOP使用其他细节

1、增加一个横切关注点,打印日志,Java类为:

package cn.itcast.oa.service.impl;public class LogHandler {    public void LogBefore() {        System.out.println("Log before method");    }    public void LogAfter() {        System.out.println("Log after method");    }}

aop.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:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">    <bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />    <bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />    <bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />    <bean id="logHandler" class="cn.itcast.oa.service.impl.LogHandler" />    <aop:config>        <aop:aspect id="time" ref="timeHandler">            <aop:pointcut id="addAllMethod"                expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />            <aop:before method="printTime" pointcut-ref="addAllMethod" />            <aop:after method="printTime" pointcut-ref="addAllMethod" />        </aop:aspect>        <aop:aspect id="log" ref="logHandler" order="2">            <aop:pointcut id="printLog"                expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />            <aop:before method="LogBefore" pointcut-ref="printLog" />            <aop:after method="LogAfter" pointcut-ref="printLog" />        </aop:aspect>    </aop:config></beans>

测试代码不变,测试结果如下:

Log before methodCurrentTime = 1482637050240Enter HelloWorldImpl1.printHelloWorld()CurrentTime = 1482637050241Log after methodLog before methodCurrentTime = 1482637050244Enter HelloWorldImpl1.doPrint()CurrentTime = 1482637050244Log after methodLog before methodCurrentTime = 1482637050244Enter HelloWorldImpl2.printHelloWorld()CurrentTime = 1482637050245Log after methodLog before methodCurrentTime = 1482637050246Enter HelloWorldImpl2.doPrint()CurrentTime = 1482637050246Log after method

要想让logHandler在timeHandler前使用有两个办法:

(1)aspect里面有一个order属性,order属性的数字就是横切关注点的顺序

(2)把logHandler定义在timeHandler前面,Spring默认以aspect的定义顺序作为织入顺序
2、我只想织入接口中的某些方法

修改一下pointcut的expression就好了:

<?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:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">    <bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />    <bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />    <bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />    <bean id="logHandler" class="cn.itcast.oa.service.impl.LogHandler" />    <aop:config>        <aop:aspect id="time" ref="timeHandler">            <aop:pointcut id="addAllMethod"                expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />            <aop:before method="printTime" pointcut-ref="addAllMethod" />            <aop:after method="printTime" pointcut-ref="addAllMethod" />        </aop:aspect>        <aop:aspect id="log" ref="logHandler" order="2">            <aop:pointcut id="printLog"                expression="execution(* cn.itcast.oa.service.HelloWorld.do*(..))" />            <aop:before method="LogBefore" pointcut-ref="printLog" />            <aop:after method="LogAfter" pointcut-ref="printLog" />        </aop:aspect>    </aop:config></beans>

表示timeHandler只会织入HelloWorld接口print开头的方法,logHandler只会织入HelloWorld接口do开头的方法

3、强制使用CGLIB生成代理

前面说过Spring使用动态代理或是CGLIB生成代理是有规则的,高版本的Spring会自动选择是使用动态代理还是CGLIB生成代理内容,当然我们也可以强制使用CGLIB生成代理,那就是里面有一个”proxy-target-class”属性,这个属性值如果被设置为true,那么基于类的代理将起作用,如果proxy-target-class被设置为false或者这个属性被省略,那么基于接口的代理将起作用

0 0
原创粉丝点击