1.目錄結構長這樣
2.application.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--向ioc容器中注入bean-->
<bean id="logAspect" class="com.zlb.spring.aop.LogAspect"></bean>
<bean id="mathCalculator" class="com.zlb.spring.aop.MathCalculator"></bean>
<!-- <context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>-->
<!--切面配置-->
<aop:config>
<!-- 配置切面表達式 -->
<aop:pointcut expression="execution(public * com.zlb.spring.aop.*.*(..))" id="pointcut"/>
<!-- 配置切面及通知 -->
<aop:aspect ref="logAspect" order="1">
<aop:before method="doBefore" pointcut-ref="pointcut"/>
<aop:after method="doAfter" pointcut-ref="pointcut"/>
<aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result"/>
<aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="exception"/>
<!-- <aop:around method="aroundMethod" pointcut-ref="pointcut"/>-->
</aop:aspect>
<!-- <aop:aspect ref="validateAspect" order="2">
<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
</aop:aspect>-->
</aop:config>
</beans>
3.java類這樣寫
(1)LogAspect.java
package com.zlb.spring.aop;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/*@Component
@Aspect
@Order(1)*/
public class LogAspect {
private org.apache.log4j.Logger logger = Logger.getLogger(this.getClass());
/* @Pointcut("execution(public * com.zlb.spring.aop.*.*(..))")
public void pointCut(){}*/
// @Before("pointCut()")
public void doBefore(JoinPoint joinPoint){
logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" start");
logger.info("args : " + Arrays.toString(joinPoint.getArgs()));
}
//@After("pointCut()")
public void doAfter(JoinPoint joinPoint){
logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" end");
}
// @AfterReturning(returning ="result",value = "pointCut()")
public void doAfterReturning(Object result){
logger.info("returned"+result);
}
//@AfterThrowing(value = "pointCut()",throwing = "exception")
public void doAfterThrowing(Exception exception){
logger.info("method exception"+exception.getMessage());
}
}
(2)MathCalculator.java
package com.zlb.spring.aop;
import org.springframework.stereotype.Component;
/*@Component*/
public class MathCalculator {
public int getDiv(int x,int y){
return x/y;
}
}
(3)測試類這樣寫
package com.zlb.spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
public static void main(String[] args) {
/*ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LogConfig.class);*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("ioc 容器舒適化完成!");
//打印logger日誌
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.getDiv(6,1);
}
}
注:沒寫的出來的log4j配置文件在上一篇基於配置類實現aop的博客中已經寫過,這裏我們是基於xml配置文件的方式來實現所以便沒有LogConfig.java
思考:我們可不可以使用<context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>加註解的方式實現aop呢?
驗證:
(1).applicationContex.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>
</beans>
(2).LogAspect.java這樣寫
package com.zlb.spring.aop;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
@Order(1)
public class LogAspect {
private org.apache.log4j.Logger logger = Logger.getLogger(this.getClass());
@Pointcut("execution(public * com.zlb.spring.aop.*.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint){
logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" start");
logger.info("args : " + Arrays.toString(joinPoint.getArgs()));
}
@After("pointCut()")
public void doAfter(JoinPoint joinPoint){
logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" end");
}
@AfterReturning(returning ="result",value = "pointCut()")
public void doAfterReturning(Object result){
logger.info("returned"+result);
}
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void doAfterThrowing(Exception exception){
logger.info("method exception"+exception.getMessage());
}
}
(2)MathCalculator.java這樣寫
@Component
public class MathCalculator {
public int getDiv(int x,int y){
return x/y;
}
}
(3)測試類這樣寫
package com.zlb.spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
public static void main(String[] args) {
/*ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LogConfig.class);*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("ioc 容器舒適化完成!");
//打印logger日誌
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.getDiv(6,1);
}
}
(4).兩種方式的運行結果都長這樣
ioc 容器舒適化完成!
[INFO][2019-06-28 14:58:19,746][main][com.zlb.spring.aop.LogAspect][class_method : com.zlb.spring.aop.MathCalculator.getDiv start]
[INFO][2019-06-28 14:58:19,747][main][com.zlb.spring.aop.LogAspect][args : [6, 1]]
[INFO][2019-06-28 14:58:19,765][main][com.zlb.spring.aop.LogAspect][class_method : com.zlb.spring.aop.MathCalculator.getDiv end]
[INFO][2019-06-28 14:58:19,765][main][com.zlb.spring.aop.LogAspect][returned6]
Process finished with exit code 0
所以:spring實現aop一共有三種方式,但是純xml的方式比較麻煩,xml與註解的方式比較常見,但是不夠靈活,所以目前企業比較流行的是基於註解與配置類的方式!