Spring AOP基于xml配置实例
SpringAOP里的几个术语,什么切面,切点之类的,官方的说明太抽象。为了更好地理解记忆,这里几下我自己的通俗的理解。
切面:就是日记类,什么前置通知后置通知(这些都是所谓的Advice)的具体方法都是写在这个日记类里的,所以把这些抽象出来的日记类就是一个切面(横切关注点)。
切点:就是某个具体的业务逻辑类,比如xxxService,也就是具体的DAO,Service之类的。
目录层级:
AOP相关的几个类就是com.aop.xmltype这个报下的4个类。
ICalculatorxml.java
package com.aop.xmltype; /** * 加减乘除接口,用于AOP测试 * * @author Wei * */ public interface ICalculatorxml { /** * 加法 * * @param a * @param b * @return a+b */ public int doAdd(int a, int b); /** * 减法 * * @param a * @param b * @return a-b */ public int doSub(int a, int b); /** * 乘法 * * @param a * @param b * @return a*b */ public int doMul(int a, int b); /** * 除法 * * @param a * @param b * @return a/b */ public int doDiv(int a, int b); /** * 求绝对值 * * @param a * @param b * @return |a-b| */ public int doAbs(int a, int b); }
CalculatorImplxml.java
package com.aop.xmltype; public class CalculatorImplxml implements ICalculatorxml { /* * { System.out.println("CalculatorImpl...{} ..."); } */ @Override public int doAdd(int a, int b) { int rtn = a + b; System.out.println(a + "+" + b + "=" + rtn); return rtn; } @Override public int doSub(int a, int b) { // TODO Auto-generated method stub return a - b; } @Override public int doMul(int a, int b) { // TODO Auto-generated method stub return a * b; } @Override public int doDiv(int a, int b) { if (b == 0) { return -1; } return a / b; } @Override public int doAbs(int a, int b) { return Math.abs(a - b); } }
MyAspectxml.java
package com.aop.xmltype; public class MyAspectxml { public void logBefore() { // String className = j.getClass().getName(); System.out.println("MyAspectxml logBefore(),开始计算...,"); } public void logAfter() { System.out.println("已经计算结束..."); } }
MyAOPTest.java
package com.aop.xmltype; import org.junit.Test; import com.util.Pub; public class MyAOPTest { ICalculatorxml cal; @Test public void testAop() { cal = new CalculatorImplxml(); cal.doAdd(13, 99); } public static void main(String[] args) { ICalculatorxml cal = (ICalculatorxml) Pub.getBeanCtx().getBean("calImplxml"); System.out.println("-----------------分割符号----------\n\n\n\n"); cal.doAdd(13, 99); } }
执行结果:
AOP相关部分的配置,完整的xml配置在最后。
bean.xml
1 <!-- 切点的bean --> 2 <bean class="com.aop.xmltype.CalculatorImplxml" id="calImplxml"></bean> 3 <!-- 切面的bean --> 4 <bean class="com.aop.xmltype.MyAspectxml" id="myaspxml"></bean> 5 <!-- aop xmlType,用xml的形式配置AOP前置通知 --> 6 <aop:config> 7 <!--aop:pointcut 其实放在这儿也可以 --> 8 <!-- <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))" 9 id="pointcut1" /> --> 10 11 <!-- 配置切面和通知 ,aop:aspect标签需要通过ref指定配置好的bean,id随便配置或者不配置,id的值可以随意起 --> 12 <aop:aspect id="myaspxml" ref="myaspxml" order="2"> 13 <!-- 配置切点,即 要被记日记的对象, aop:pointcut 放在这儿也可以 ,切点不需要根对应的bean相关联, 14 只要expression指定的方法所在的类被Spring扫描得到就行,即只要所在的类配置了bean就可以 --> 15 <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))" 16 id="pointcut1" /> 17 <!-- 切面里的具体的用于记录的方法就是一个通知,需要用通过pointcut-ref来指定具体的切点, --> 18 <aop:before method="logBefore" pointcut-ref="pointcut1" /> 19 <aop:after method="logAfter" pointcut-ref="pointcut1" /> 20 21 </aop:aspect> 22 23 </aop:config>
完整的beans.xml的配置如:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 10 <bean id="moocAppctx" class="imooc_spring.test.aware.MoocApplicationContext" 11 init-method="hhhh"> 12 </bean> 13 14 <!-- 引入db.properties --> 15 <context:property-placeholder location="classpath:db.properties" /> 16 17 <!-- 配置C3P0数据源 --> 18 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 19 <property name="jdbcUrl" value="${jdbc.url}"></property> 20 <property name="driverClass" value="${jdbc.driverName}"></property> 21 <property name="user" value="${jdbc.username}"></property> 22 <property name="password" value="${jdbc.pwd}"></property> 23 </bean> 24 25 <!-- 配置 Spring 的 org.springframework.jdbc.core.JdbcTemplate --> 26 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 27 <property name="dataSource" ref="dataSource"></property> 28 </bean> 29 30 <bean id="moocBeanNameAware" class="imooc_spring.test.aware.MoocBeanNameAware"></bean> 31 32 <!-- 测试 SpEL: 可以为属性进行动态的赋值(了解) --> 33 <bean id="girl" class="com.helloworld.User"> 34 <property name="userName" value="周迅"></property> 35 </bean> 36 37 <!-- <bean id="boy" class="com.helloworld.User" init-method="init" destroy-method="destroy"> 38 <property name="userName" value="高胜远"></property> <property name="wifeName" 39 value="#{girl.userName}"></property> </bean> --> 40 41 <bean id="girl2" class="com.helloworld.User2"> 42 <property name="userName" value="Talor Swift"></property> 43 </bean> 44 45 <!-- autowired测试,自动装配测试 --> 46 <bean id="people" class="test.spring.autowired.Person" scope="prototype" 47 autowire="byName"> 48 <property name="name" value="小明"></property> 49 <!-- <property name="cat" ref="cat222"></property> --> 50 <!-- <property name="cat" ref="cat1"></property> --> 51 </bean> 52 53 <bean id="cat" class="test.spring.autowired.Cat" scope="prototype"> 54 <property name="name" value="波斯猫"></property> 55 </bean> 56 <!-- <bean id="cat222" class="test.spring.autowired.Cat"> <property name="name" 57 value="我是小喵喵"></property> </bean> --> 58 59 60 61 <bean id="people2" class="test.spring.autowired.Person" scope="prototype" 62 autowire="byName"> 63 <property name="name" value="小明"></property> 64 <property name="cat" ref="cat222"></property> 65 </bean> 66 67 <bean id="cat222" class="test.spring.autowired.Cat" scope="prototype"> 68 <property name="name" value="波斯猫"></property> 69 </bean> 70 71 <!--context:component-scan 指定 扫描的包 --> 72 <!--可以通过 resource-pattern 指定扫描的资源, resource-pattern="myrepository/*.class" 73 的含义: 只扫描 base-package 对应包下的 目录为 myrepository 的所有java Bean --> 74 <!-- <context:component-scan base-package="imooc_spring.test.anotation" 75 resource-pattern="myrepository/*.class"></context:component-scan> --> 76 77 <!-- context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" 78 子节点指定排除哪些注解 context:include-filter type="annotation" 需要结合context:component-scan 79 标签的 use-default-filters="false"来使用 context:exclude-filter type="assignable" 80 这个expression指的是自己写的类,意思排除哪些类 expression="imooc_spring.test.anotation.TestObj" --> 81 <context:component-scan base-package="imooc_spring.test.anotation"> 82 <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" 83 /> --> 84 85 <!-- <context:exclude-filter type="assignable" expression="imooc_spring.test.anotation.TestObj" 86 /> --> 87 88 89 </context:component-scan> 90 <context:component-scan base-package="com.aop"></context:component-scan> 91 92 <!-- aop测试,需要引入aop命名空间 --> 93 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 94 95 96 97 98 <!-- aop annotationType, --> 99 100 101 102 103 104 105 106 107 108 109 110 111 <!-- 切点的bean --> 112 <bean class="com.aop.xmltype.CalculatorImplxml" id="calImplxml"></bean> 113 <!-- 切面的bean --> 114 <bean class="com.aop.xmltype.MyAspectxml" id="myaspxml"></bean> 115 <!-- aop xmlType,用xml的形式配置AOP前置通知 --> 116 <aop:config> 117 <!--aop:pointcut 其实放在这儿也可以 --> 118 <!-- <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))" 119 id="pointcut1" /> --> 120 121 <!-- 配置切面和通知 ,aop:aspect标签需要通过ref指定配置好的bean,id随便配置或者不配置,id的值可以随意起 --> 122 <aop:aspect id="myaspxml" ref="myaspxml" order="2"> 123 <!-- 配置切点,即 要被记日记的对象, aop:pointcut 放在这儿也可以 ,切点不需要根对应的bean相关联, 124 只要expression指定的方法所在的类被Spring扫描得到就行,即只要所在的类配置了bean就可以 --> 125 <aop:pointcut expression="execution (* com.aop.xmltype.CalculatorImplxml.*(..))" 126 id="pointcut1" /> 127 <!-- 切面里的具体的用于记录的方法就是一个通知,需要用通过pointcut-ref来指定具体的切点, --> 128 <aop:before method="logBefore" pointcut-ref="pointcut1" /> 129 <aop:after method="logAfter" pointcut-ref="pointcut1" /> 130 131 </aop:aspect> 132 133 </aop:config> 134 135 136 137 138 139 140 141 </beans>
项目名为:imooc_spring.rar,在我的qq微云上。