<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ly.spring</groupId> <artifactId>spring05</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--用於解析切入點表達式--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.6</version> </dependency> <!--用於整合junit--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <!--解決IDEA maven變動後自動重置LanguageLevel和JavaCompiler版本的問題--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>13</source> <target>13</target> </configuration> </plugin> </plugins> </build> </project>
package com.ly.spring.domain; import java.io.Serializable; public class Account implements Serializable { private String accountName; public String getAccountName() { return accountName; } public void setAccountName(String accountName) { this.accountName = accountName; } @Override public String toString() { return "Account{" + "accountName='" + accountName + '\'' + '}'; } }
package com.ly.spring.service; import com.ly.spring.domain.Account; import java.util.List; public interface IAccountService { public List<Account> findAll(); }
package com.ly.spring.service.impl; import com.ly.spring.domain.Account; import com.ly.spring.service.IAccountService; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service("accountService") public class AccountServiceImpl implements IAccountService { @Override public List<Account> findAll() { System.out.println("AccountServiceImpl---findAll"); List<Account> list = new ArrayList<>(); Account account = new Account(); account.setAccountName("hehe"); list.add(account); return list; } }
package com.ly.spring.utils; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component("logUtil") //@Aspect:指定此類爲切面通知類 @Aspect public class LogUtil { //@Pointcut:配置切入點 @Pointcut("execution(* com.ly.spring.service.impl.*.*(..))") private void pointCut1() {} //@Before:配置前置通知方法並指定切入點 @Before("pointCut1()") public void beforeFunc() { System.out.println("---前置通知---"); } //@AfterReturning:配置後置通知方法並指定切入點 @AfterReturning("pointCut1()") public void afterReturnFunc() { System.out.println("---後置通知---"); } //@AfterThrowing:配置異常通知方法並指定切入點 @AfterThrowing("pointCut1()") public void afterThrowFunc() { System.out.println("---異常通知---"); } //@After:配置最終通知方法並指定切入點 @After("pointCut1()") public void afterFunc() { 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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--配置註解掃描的包--> <context:component-scan base-package="com.ly.spring"></context:component-scan> <!--開啓AOP註解配置--> <!-- AOP註解配置說明: 一、在用註解配置使用4個經常使用通知時,最終通知會在後置通知前執行 二、如果要用純註解方式能夠在配置類上加@EnableAspectJAutoProxy註解 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
package com.ly.spring.test; import com.ly.spring.domain.Account; import com.ly.spring.service.IAccountService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; //替換junit的main方法 @RunWith(SpringJUnit4ClassRunner.class) //指定spring配置文件的位置 @ContextConfiguration(locations = "classpath:bean.xml") public class MainTest { @Autowired private IAccountService accountService; @Test public void test1() { List<Account> result = accountService.findAll(); System.out.println(result); } }
package com.ly.spring.utils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component("logUtil") //@Aspect:指定此類爲切面通知類 @Aspect public class LogUtil { //@Pointcut:配置切入點 @Pointcut("execution(* com.ly.spring.service.impl.*.*(..))") private void pointCut1() {} public void beforeFunc() { System.out.println("---前置通知---"); } public void afterReturnFunc() { System.out.println("---後置通知---"); } public void afterThrowFunc() { System.out.println("---異常通知---"); } public void afterFunc() { System.out.println("--最終通知--"); } //@Around:配置環繞通知方法並指定切入點 @Around("pointCut1()") public Object arroundFunc(ProceedingJoinPoint pjp) { try { Object result = null; Object[] args = pjp.getArgs(); beforeFunc();//前置通知 result = pjp.proceed(args); afterReturnFunc();//後置通知 return result; }catch (Throwable t) { afterThrowFunc();//異常通知 throw new RuntimeException(t); }finally { afterFunc();//最終通知 } } }