zbb_ioc_aop
https://pan.baidu.com/disk/home#/all?vmode=list&path=%2Fcode%2Fspring
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zbb</groupId>
<artifactId>zbb_test01</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>zbb_test01 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- aop aspect注解导包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
<build>
<finalName>zbb_test01</finalName>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>springMVC</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- spring 配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring-mvc 配置 -->
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.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" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
<!-- Scans for application @Components to deploy -->
<context:component-scan base-package="com.zbb" />
</beans>
spring-mvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 扫描控制器类 -->
<context:component-scan base-package="com.zbb" />
<!-- 启动AspectJ支持 只对扫描过的bean有效 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--开启注解 -->
<mvc:annotation-driven />
<!-- jsp视图解析器 -->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
LoggerAspect.java
package com.zbb.aspect;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect // 该标签把LoggerAspect类声明为一个切面
@Order(1) // 设置切面的优先级:如果有多个切面,可通过设置优先级控制切面的执行顺序(数值越小,优先级越高)
@Component // 该标签把LoggerAspect类放到IOC容器中
public class LoggerAspect {
/**
* 定义一个方法,用于声明切入点表达式,方法中一般不需要添加其他代码 使用@Pointcut声明切入点表达式
* 后面的通知直接使用方法名来引用当前的切点表达式;如果是其他类使用,加上包名即可
*/
@Pointcut("execution(public * com.zbb.controller.*.*(..))")
public void declearJoinPointExpression() {
}
@Pointcut("execution(public * com.zbb.service.*.*(..))")
public void declearJoinPointExpression2() {
}
/**
* 前置通知
*
* @param joinPoint
*/
@Before("declearJoinPointExpression()") // 该标签声明次方法是一个前置通知:在目标方法开始之前执行
public void beforMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("this method " + methodName + " begin. param<" + args + ">");
}
/**
* 后置通知(无论方法是否发生异常都会执行,所以访问不到方法的返回值)
*
* @param joinPoint
*/
@After("declearJoinPointExpression()")
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.");
}
/**
* 返回通知(在方法正常结束执行的代码) 返回通知可以访问到方法的返回值!
*
* @param joinPoit
*/
@AfterReturning(value = "declearJoinPointExpression()", returning = "result")
public void afterReturnMethod(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.result<" + result + ">");
}
/**
* 异常通知(方法发生异常执行的代码) 可以访问到异常对象;且可以指定在出现特定异常时执行的代码
*
* @param joinPoint
* @param ex
*/
@AfterThrowing(value = "declearJoinPointExpression()", throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.ex message<" + ex + ">");
}
/**
* 环绕通知(需要携带类型为ProceedingJoinPoint类型的参数)
* 环绕通知包含前置、后置、返回、异常通知;ProceedingJoinPoin 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值,返回值即目标方法的返回值
*
* @param joinPoint
*/
@Around(value = "declearJoinPointExpression()")
public Object aroundMethod(ProceedingJoinPoint point) {
Object result = null;
String methodName = point.getSignature().getName();
try {
// 前置通知
System.out.println("The method " + methodName + " start. param<" + Arrays.asList(point.getArgs()) + ">");
// 执行目标方法
result = point.proceed();
// 返回通知
System.out.println("The method " + methodName + " end. result<" + result + ">");
} catch (Throwable e) {
// 异常通知
System.out.println("this method " + methodName + " end.ex message<" + e + ">");
throw new RuntimeException(e);
}
// 后置通知
System.out.println("The method " + methodName + " end.");
return result;
}
/**
* 前置通知
*
* @param joinPoint
*/
@Before("declearJoinPointExpression2()") // 该标签声明次方法是一个前置通知:在目标方法开始之前执行
public void beforMethod2(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("this method " + methodName + " begin. param<" + args + ">");
}
/**
* 后置通知(无论方法是否发生异常都会执行,所以访问不到方法的返回值)
*
* @param joinPoint
*/
@After("declearJoinPointExpression2()")
public void afterMethod2(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.");
}
/**
* 返回通知(在方法正常结束执行的代码) 返回通知可以访问到方法的返回值!
*
* @param joinPoit
*/
@AfterReturning(value = "declearJoinPointExpression2()", returning = "result")
public void afterReturnMethod2(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.result<" + result + ">");
}
/**
* 异常通知(方法发生异常执行的代码) 可以访问到异常对象;且可以指定在出现特定异常时执行的代码
*
* @param joinPoint
* @param ex
*/
@AfterThrowing(value = "declearJoinPointExpression2()", throwing = "ex")
public void afterThrowingMethod2(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().getName();
System.out.println("this method " + methodName + " end.ex message<" + ex + ">");
}
/**
* 环绕通知(需要携带类型为ProceedingJoinPoint类型的参数)
* 环绕通知包含前置、后置、返回、异常通知;ProceedingJoinPoin 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值,返回值即目标方法的返回值
*
* @param joinPoint
*/
@Around(value = "declearJoinPointExpression2()")
public Object aroundMethod2(ProceedingJoinPoint point) {
Object result = null;
String methodName = point.getSignature().getName();
try {
// 前置通知
System.out.println("The method " + methodName + " start. param<" + Arrays.asList(point.getArgs()) + ">");
// 执行目标方法
result = point.proceed();
// 返回通知
System.out.println("The method " + methodName + " end. result<" + result + ">");
} catch (Throwable e) {
// 异常通知
System.out.println("this method " + methodName + " end.ex message<" + e + ">");
throw new RuntimeException(e);
}
// 后置通知
System.out.println("The method " + methodName + " end.");
return result;
}
}
TestController.java
package com.zbb.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zbb.service.TestService;
@RestController
@RequestMapping("test")
public class TestController {
@Autowired
TestService testService;
@RequestMapping("t1")
public void t1(){
testService.t2();
}
}
TestService.java
package com.zbb.service;
import org.springframework.stereotype.Service;
@Service
public class TestService {
public void t2(){
System.out.println("asdfafasdf");
}
}