一,AOP原理和基础 :
a.面向切面(方面) 编程,扩展的功能根不该原代码b.采用横向抽取机制,取代了传统的纵向继承体系重复性代码(性能监控,事物管理,安全性检查,缓存)
纵向继承体系是定义个父类来实现代码复用
Joinpoint (连接点):类中可以被增强的那些方法叫连接点
Pointcut (切入点):在类中可以有很多方法可以被增强,比如实际操作中,只是增强了中add和update方法,实际增强的方法叫做切入点
Advice (增强/通知):增强的逻辑,称为增强,如扩展日志功能
前置通知:add()方法之前执行
后置通知:在方法之后执行
异常通知:在方法出现异常执行
最终通知:在后置之后执行
环绕通知:方法之前和之后执行,如执行时间的计算
Aspect (切面):把我们的增强应用到具体方法上面,过程称为切面-->把增强用到切入点的过程
Introduction (引介): 在不修改代码的前提下给运行期的类动态添加方法和属性
Target(目标对象) :AOp使用动态代理的代理对象
Weaving(织入):把我们的增强应用到具体目标,过程称为织入
Proxy(代理) :一个类被AOP织入增强后就产生一个结果代理类
二,AOP操作:--->Aspectj实现
tip: a.需要引入aspects.jar来实现AOP操作
b.需要aop约束
(1),基于Aspectj的xml配置
(2),基于Aspectj注解方式
1.切入点:实际增强的方法
2.常用的表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
*任意修饰符public private protect
(1),execution(* com.gog.aop.Book.add(..))
任意修饰下 的add方法AOp操作 add(..)可以有参数
(2),execution(* com.gog.aop.Book.*(..))
任意修饰下 的Book中所有方法AOp操作 add(..)可以有参数
(3),execution(* *.*(..))
任意修饰下 所有类的所有方法 add(..)可以有参数
(4),匹配所有save开头的方法 execution(* save*(..))
eg: savebook(); saveUser();
三,Advice 的实现
book 是切入点MyBookUp是增强方法类
<bean id="b1ook" class="com.gog.aop.Book" ></bean>
<bean id="myBookUp" class="com.gog.aop.MyBookUp" ></bean>
<!-- 配置AOp 前置增强操作 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.gog.aop.Book.*(..))" id="pointcut1"></aop:pointcut>
<!-- 配置 切面
把增强用到方法上
-->
<aop:aspect ref="myBookUp">
<!-- 配置增强类型,是前置还是后置
method 增强的方法
pointcut-ref 切入点
-->
<aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
</aop:aspect>
</aop:config>
<!-- 配置AOp后置增强操作 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.gog.aop.Book.*(..))" id="pointcut1"></aop:pointcut>
<!-- 配置 切面
把增强用到方法上
-->
<aop:aspect ref="myBookUp">
<!-- 配置增强类型,是前置还是后置
method 增强的方法
pointcut-ref 切入点
-->
<aop:after method="after1" pointcut-ref="pointcut1" />
</aop:aspect>
</aop:config>
<!-- 配置AOp还让给增强操作 -->
<aop:config>
<!-- 配置切入点 表达式 -->
<aop:pointcut expression="execution(* com.gog.aop.Book.*(..))" id="pointcut1"></aop:pointcut>
<!-- 配置 切面
把增强用到方法上
-->
<aop:aspect ref="myBookUp">
<!-- 配置增强类型,是前置还是后置
method 增强的方法
pointcut-ref 切入点
-->
<aop:around method="around1" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
特别注意的是环绕增强需要参数 ProceedingJoinPoint.proceed();方式代表执行切入点
public void after1(){
System.out.println("MyBookUp after1 后置增强");
}
public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("MyBookUp around1 环绕增强 第一次");
//执行add() ,即执行切入点
proceedingJoinPoint.proceed();
System.out.println("MyBookUp around1 环绕增强 第二次i");
}.
四 , Spring-struts2 整合 需要spring-web.jar来整合,配置监听器ConText
(1),所需要jaraopalliance-1.0.jar
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
aspectjweaver-1.6.11.jar
commons-fileupload-1.3.jar
commons-io-2.0.1.jar
commons-lang3-3.1.jar
commons-logging-1.1.1.jar
commons-logging-1.1.3.jar
freemarker-2.3.19.jar
javassist-3.11.0.GA.jar
log4j-1.2.17.jar
ognl-3.0.6.jar
spring-aop-3.2.0.RELEASE.jar
spring-aspects-3.2.0.RELEASE.jar
spring-beans-3.2.0.RELEASE.jar
spring-context-3.2.0.RELEASE.jar
spring-core-3.2.0.RELEASE.jar
spring-expression-3.2.0.RELEASE.jar
spring-web-3.2.0.RELEASE.jar
spring-webmvc-3.2.0.RELEASE.jar
struts2-core-2.3.15.3.jar
xwork-core-2.3.15.3.jar
(2),配置xml
<!-- 3.指定spring配置文件的位置 contextConfigLocation 属性来着监听器的父类ContextLoader -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 1. 配置struts2的拦截器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param> <param-name>struts.action.extension</param-name> <param-value>do</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 2.配置spring监听器 需要spring-web整合jar -->
<listener>
<!-- 这个类继承字ServletContextListener这个接口
这里需要配置spring的默认配置文件位置/WEB-INF/applicationContext.xml
所以需要修改的话走 3.
-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
(3) ,struts2.xml
配置action,拦截请求userAction.do
<package name="demo1" extends="struts-default" namespace="/">
<action name="userAction" class="com.gog.action.UserAction"></action>
</package>
(4),spring配置文件
<bean id="userDao" class="com.gog.dao.UserDao"></bean>
<bean id="userService" class="com.gog.service.UserService">
<!-- name 对应UserService中的属性名称 ,但必须实现set方法 -->
<property name="user" ref="userDao"></property>
</bean>
(5),java代码对应的UserAction
a.
public class UserAction extends ActionSupport {
public String execute() throws Exception {
System.out.println("start Action");
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) context.getBean("userService");
service.add();
return NONE;
}
}
b.
UserService.java
public class UserService {
private UserDao user ;
public void setUser(UserDao user) {..}
public void add() {..}
}
(6)可以访问userAction.do查看日志输出