Spring AOP的开发
Spring AOP定义
①是一种编程范式,一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充。
②AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点。
③在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里。
Spring AOP优点
①降低模块耦合度
②使系统容易扩展
③更好的代码复用性
Spring AOP术语
基于XML配置开发
1.相关jar包
spring-aop-4.3.3.RELEASE.jar,
aspectjweaver-1.8.5.jar
aspectjrt-1.8.5.jar
2.Spring XML配置文件
在resource文件里面整个conifg文件夹,spring xml文件放里面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
">
<!--以上是类似于引文件,等相关配置-->
<!-- 注册业务BEAN -->
<bean id="bankService" class="init.wuji.logger.BankServiceImpl">
</bean>
<bean id="loggerAspect" class="init.wuji.logger.LoggerAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* init.wuji.logger.*.*(..))" id="loggerPointCut"/>
<!--包名.类名.方法名() 如果全类全方法就用*-->
<aop:aspect ref="loggerAspect">
<aop:before method="logerBefore" pointcut-ref="loggerPointCut"/>
</aop:aspect>
</aop:config>
</beans>
3.其他类文件的部署
我的是在init.wuji.logger包里面整了这些类。
下面这是接口
package init.wuji.logger;
import java.math.BigDecimal;
public interface BankService {
public BigDecimal transfer(String target, String source, BigDecimal money);
public void test();
}
下面这是实现类
package init.wuji.logger;
import java.math.BigDecimal;
public class BankServiceImpl implements BankService{
public BigDecimal transfer(String target, String source, BigDecimal money) {
System.out.println(source + "向" + target + "轉賬:" + money);
return new BigDecimal("12345612");
}
public void test() {
System.out.println("=============BankServiceImpl=====test===========>");
}
}
下面这是本文重点
package init.wuji.logger;
import org.aspectj.lang.JoinPoint;
public class LoggerAspect {
public void logerBefore(JoinPoint jp) {
String methodName = jp.getSignature().getName();
System.out.println("method: " + methodName + "將要被執行!");
Object[] args = jp.getArgs();
for(Object arg : args) {
System.out.println("=============參數:>" + arg);
}
}
}
main方法测试运行
package init.wuji.logger;
import java.math.BigDecimal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext-xml-aop.xml");
BankService bsp = ioc.getBean("bankService", BankService.class);
bsp.transfer("張世交", "馬雲", new BigDecimal("100000000"));
}
}
控制台显示结果为
16:28:05.907 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bankService'
16:28:05.907 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
16:28:06.634 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'loggerAspect'
method: transfer將要被執行!
=============參數:>張世交
=============參數:>馬雲
=============參數:>100000000
馬雲向張世交轉賬:100000000
另外通知方法有多种,我只是给了一种前置通知还有
后置通知、返回通知、异常通知、环绕通知、与其类似。
其重大区别是 环绕通知很强力,权力大,可隐藏返回值
所以原方法有return,环绕通知必须也有return。
基于注解的开发
相关jar与xml开发一样
Spring XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
">
<!-- 注册业务BEAN -->
<context:component-scan base-package="init.wuji.anno.springaop"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 仅仅是在此处来了个自动扫描 -->
</beans>
logger类的编写
//包名为init.wuji.anno.springaop
通知类Java类编写:使用@Aspect 和@Component标记为切面的Spring Bean组件
package init.wuji.anno.springaop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AnnoLoggerAspect {
@Before("execution(* init.wuji.anno.springaop.*.*(..))")
public void logerBefore(JoinPoint jp) {
String methodName = jp.getSignature().getName();
System.out.println("method: " + methodName + "將要被執行!");
Object[] args = jp.getArgs();
for(Object arg : args) {
System.out.println("=============參數:>" + arg);
}
}
}
上面的代码前置通知用的是@before(作用域)
后置通知则为@After()
异常通知则为@AffterThrowing()
环绕通知则为@Around()
普通类
@Service()
package init.wuji.anno.springaop;
import java.math.BigDecimal;
import org.springframework.stereotype.Service;
@Service
public interface BankService {
public BigDecimal transfer(String target, String source, BigDecimal money);
public void test();
}
package init.wuji.anno.springaop;
import java.math.BigDecimal;
import org.springframework.stereotype.Service;
@Service("bankService")
public class BankServiceImpl implements BankService{
public BigDecimal transfer(String target, String source, BigDecimal money) {
System.out.println(source + "向" + target + "轉賬:" + money);
return new BigDecimal("12345612");
}
public void test() {
System.out.println("=============BankServiceImpl=====test===========>");
}
}
主方法
package init.wuji.anno.springaop;
import java.math.BigDecimal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext-anno-aop2.xml");
BankService bsp = ioc.getBean("bankService", BankService.class);
bsp.transfer("張世交", "馬雲", new BigDecimal("100000000"));
}
}
运行结果
16:50:06.225 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bankService'
16:50:06.254 [main] DEBUG org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory - Found AspectJ method: public void init.wuji.anno.springaop.AnnoLoggerAspect.logerBefore(org.aspectj.lang.JoinPoint)
method: transfer將要被執行!
=============參數:>張世交
=============參數:>馬雲
=============參數:>100000000
馬雲向張世交轉賬:100000000