AOP是面向方面的编程,在实际开发之中,AOP都会工作在业务层;因为业务层要调用数据层,而业务层也要完成所有辅助性的数据层操作.
范例:定义业务层操作接口
package cn.zwb.service; import cn.zwb.vo.Member; public interface IMemberService { public boolean insert(Member vo); }
package cn.zwb.service.impl; import org.springframework.stereotype.Service; import cn.zwb.service.IMemberService; import cn.zwb.vo.Member; @Service public class MemberServiceImpl implements IMemberService{ @Override public boolean insert(Member vo) { System.out.println("数据层调用member="+vo); return false; } }
此时的业务层里面只关系有核心的业务功能,核心的功能就是调用了业务层的代码
随后所有的辅助性操作功能都通过Spring容器动态配置.
范例:为项目配置Annocation的扫描支持
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="cn.zwb.vo.Member"/> </beans>
但是这种操作并不严格,还需要准备出相应的辅助性功能,那么这些辅助性的功能可以单独定义在一个切面的处理类之中.
范例:定义切面处理类
package cn.zwb.aop; public class ServiceAspect { public void serviceBefore(){ System.out.println("AO切面 执行日志记录操作"); } public void serviceAfter(){ System.out.println("AOP切面 执行事务处理操作"); } }
默认情况下Spring之中并不会去开启切面的操作模式,所以如果要想开启切面必须引入aop的命名空间;
范例:修改applicationContext.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="cn.zwb"/> </beans>
于是下面的任务就是在applicationContext.xml文件之中利用配置文件组织切面
范例:定义切面引用
<aop:config proxy-target-class="true"> <!-- 首先定义程序的切入点 --> <aop:pointcut expression="execution(* cn.zwb..*.*(..))" id="pointcut"/> <!-- 定义要使用的面向切面的处理类 --> <aop:aspect ref="serviceAspect"> <aop:before method="serviceBefore" pointcut-ref="pointcut"/> <aop:after method="serviceAfter" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
此时的业务层里面没有出现任何的与业务层的核心操作有关的功能代码,而所有的辅助功能都会以切面的形式出现在项目的执行之中,那么这些切面就相当于最早的代理类.
现在的整个配置过程之中,其基本的操作意义都可以一看就明白,但是最为重要的是切入点的设置;
execution(* cn.zwb..*.*(..))
这种语法就是AspecJ定义的切入点操作的语法.此语法结构如下:
execution(修饰符匹配? 返回值类型 操作类型匹配? 名称匹配(参数匹配) 抛出异常匹配 )
以上的语法详细的解释如下:
●修饰符:public,private,只能够出现0次或1次(本次没有出现);
●返回值(execution(* cn.zwb..*.*(..))):返回值如果是*表示返回任意类型
●名称匹配(execution(* cn.zwb..*.*(..))):表示的是具体要使用此切面的程序类,如果写上的是"cn.zwb"则表示在这个包中,而如果后面出现了".."表示在任意子包下"*.*"表示的是任意类的任意方法(execution(* cn.zwb..*.*(..)))
●方法参数(execution(* cn.zwb..*.*(..))):使用".."表示匹配任意多个参数,如果使用的是"*"表示匹配任意一个参数.