主要表现是使用AspectJ的expression的操作:
execution(modifiers-pattern ret-type-pattern declaring-type-pattern name-pattern(param-pattern) throws-pattern)
注意在使用之前需要在xml文件的beans标签中加入新的schame文件aop:并在Eclipse中进行关联配置
<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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
</beans>
普通的方法:
public int setName(String name) throws Excepption{
}
定义代理的方法:
execution(modifiers-pattern ret-type-pattern declaring-type-pattern name-pattern(param-pattern) throws-pattern)
除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的。
返回类型模式决定了方法的返回类型必须依次匹配一个连接点。
你会使用的最频繁的返回类型模式是 *,它代表了匹配任意的返回类型。
一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。
你可以使用 * 通配符作为所有或者部分命名模式。
参数模式稍微有点复杂:
() 匹配了一个不接受任何参数的方法
而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)
模式 (*) 匹配了一个接受一个任何类型的参数的方法
模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型
下面给出一些常见切入点表达式的例子
1)任意包下的任意类中的公共方法的执行:
execution(public * *(..))
2)任何一个以“set”开始的方法的执行:
execution(* set*(..))
3)AccountService 接口的任意方法的执行:
execution(* com.briup.service.AccountService.*(..))
4)定义在service包里的任意类的任意方法的执行: 当前包下(./)
execution(* com.briup.service.*.*(..))
5)定义在service包或者子包(../)里的任意方法的执行:
execution(* com.briup.service..*.*(..))
单独的配置aop的代理
<!-- 配置aop的代理 -->
<aop:config>
<!-- 定义一个切入点 并给切入点起名为myPointCut -->
<!-- 切入点是一组连接点的集合 -->
<aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..))" id="myPointCut"/>
<!-- 定义哪一个advice在哪一个切入点上面起作用 -->
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="myPointCut" />
</aop:config>
<!--
解释上面的配置 expression="execution(public * com.briup.aop.service.*.*(..))"
这个引号""里面就是用表达式的方式来定义切入点,只要是符合我们这个表达式要求的
方法就是我们的连接点,连接点的集合就是我们要定义的切入点。
表达式中从左到右的*号:
第一个* 表示方法的返回类型不限。
第二个* 表示包中的任意一个类
第三个* 表示类中的任意一个方法
同时方法的参数也没有限制.
-->
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean>
<!-- 配置前置通知 -->
<bean name="beforeAdvice" class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>
<!-- 配置目标对象 -->
<bean name="target" class="com.briup.aop.service.AccountServiceImpl">
<!-- 注入相关的类 -->
<property name="accountDao" ref="accountDao"></property>
<property name="account" ref="account"></property>
</bean>
<!-- 配置dao层对象accountDao和account对象,为了给service注入 -->
<bean name="accountDao" class="com.briup.aop.dao.AccountDaoImpl"></bean>
<bean name="account" class="com.briup.aop.pojo.Account">
<property name="id" value="1"></property>
<property name="name" value="tom"></property>
<property name="balance" value="20000"></property>
</bean>
<!-- 使用AOP专属标签配置产生代理对象的工厂类 -->
<aop:config>
<!-- 定义切入点,切入点就是一组集合,连接点,在spring中的方法 -->
<aop:pointcut id="myPoint" expression="execution(* com.briup.aop.service.AccountServiceImpl.*(..))" />
<!-- 定义哪一个advice带的切面类中的代码,并将其织入到指定的切入点上 -->
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="myPoint" />
</aop:config>
</beans>
测试:
// 知识点:使用<aop >标签来配置aop功能
@Test
public void aop_aopconfig() {
try {
String path = "com/briup/aop/aopConfig/aopconfig.xml";
ApplicationContext container = new ClassPathXmlApplicationContext(path);
IAccountService proxy=(IAccountService) container.getBean("target");
proxy.bankAction();
System.out.println(proxy.getClass());
} catch (Exception e) {
e.printStackTrace();
}
}
当有多个包下面的类中的方法需要被代理,怎样写:
1.用or连接起来
<aop:pointcut id="myPoint" expression="execution(* com.briup.aop.service.AccountServiceImpl.*(..)) or execution(* com.briup.aop.service.AccountServiceImpl.*(..))"/>
注意:<aop:config proxy-target-class=“true”> 如果这样配置则是强制使用CGLIB方式进行代理
2.写多个aop:pointcut标签,但是要id名一样
<aop:pointcut id="myPoint1" expression="execution(* com.briup.aop.service.AccountServiceImpl.*(..))"/>
<aop:pointcut id="myPoint2" expression="execution(* com.briup.aop.service.service..*.*(..))"/>