Jar包
1>aspectJ的Jar包
2>Spring用于整合aspectJ的Jar包
3>Spring-aop
4>aop联盟给出的aop规范Jar包
5)连接点:可以被增强的目标方法,称为连接点方法
6)切入点:真正被增强的连接点方法
7)切入点表达式:
execution(访问权限 返回类型 全限定性方法名(参数列表) 抛出的异常)
其中返回类型与方法名是不能省略的
execution(* *.SomeService.*(..))
package com.abc.xml;
// 业务接口
public interface ISomeService {
void doFirst();
void doSecond();
String doThird();
}
package com.abc.xml;
// 目标类
public class SomeServiceImpl implements ISomeService {
// 目标方法
@Override
public void doFirst() { // com.abc.xml.SomeServiceImpl.doFirst()
System.out.println("执行主业务逻辑doFirst()");
}
// 目标方法
@Override
public void doSecond() {
System.out.println("执行主业务逻辑doSecond()");
}
// 目标方法
@Override
public String doThird() {
System.out.println("执行主业务逻辑doThird()");
return "aynu";
}
}
package com.abc.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
// 定义切面
public class MyAspcet {
// 前置通知方法(Advice):用于在目标方法执行之前先执行的方法,用于增强目标方法的方法
public void before() {
System.out.println("执行前置通知方法before()");
}
public void before2(JoinPoint jp) {
System.out.println("执行前置通知方法before2() jp = " + jp);
}
// 后置通知方法
public void afterReturning() {
System.out.println("执行后置通知方法afterReturning()");
}
// 后置通知方法
public void afterReturning(Object result) {
if (result != null) {
result = ((String) result).toUpperCase();
}
System.out.println("执行后置通知 目标方法返回结果为result " + result);
}
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
Object proceed = pjp.proceed();
if (proceed != null) {
proceed = ((String) proceed).toUpperCase();
}
System.out.println("执行环绕通知 目标方法返回结果为proceed " + proceed);
return proceed;
}
public void myThorwing(Exception ex) {
System.out.println("异常" + ex.getMessage());
}
public void myAfter() {
System.out.println("最后方法()");
}
}
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册目标对象 -->
<bean id="someService" class="com.abc.xml.SomeServiceImpl" />
<!-- 注册切面 -->
<bean id="myAspect" class="com.abc.xml.MyAspcet" />
<!-- AOP配置 -->
<aop:config>
<!-- 定义三个切入点 -->
<aop:pointcut expression="execution(* *..SomeServiceImpl.doFirst(..))"
id="doFirstPC" />
<aop:pointcut expression="execution(* *..SomeServiceImpl.doSecond(..))"
id="doSecondPC" />
<aop:pointcut expression="execution(* *..SomeServiceImpl.doThird(..))"
id="doThirdPC" />
<aop:aspect ref="myAspect">
<!-- 前置通知 -->
<aop:before method="before()" pointcut-ref="doFirstPC" />
<aop:before method="before2(org.aspectj.lang.JoinPoint)"
pointcut-ref="doFirstPC" />
<!-- 后置通知 -->
<aop:after-returning method="afterReturning()"
pointcut-ref="doThirdPC" />
<aop:after-returning method="afterReturning(java.lang.Object)"
returning="result" pointcut-ref="doThirdPC" />
<!-- 环绕通知 -->
<aop:around method="myAround(org.aspectj.lang.ProceedingJoinPoint)"
pointcut-ref="doThirdPC" />
<!-- 异常通知 -->
<aop:after-throwing method="myThorwing"
pointcut-ref="doThirdPC" throwing="ex" />
<!-- 最终通知 -->
<aop:after method="myAfter()" pointcut-ref="doThirdPC" />
</aop:aspect>
</aop:config>
</beans>
package com.abc.xml;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01() {
// 从类路径下加载Spring配置文件,获取Spring容器对象
String conf = "com/abc/xml/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
// 从容器中获取someService对象
ISomeService service = (ISomeService) ac.getBean("someService");
service.doFirst();
System.out.println("--------------------------------");
service.doSecond();
System.out.println("--------------------------------");
String result = service.doThird();
System.out.println(result);
}
}
注意appication.xml文件约束条件修改为AOP,否则引导不出aop-config配置。
spring4与5的jar包有区别,5的配置方法名需要加括号及含参路径,4则不需。