步骤:
1、首先要导入spring-aop-4.3.17.RELEASE.jar(使用maven添加)
2、在配置文件applicationContext.xml引入新的命名空间(即为xml约束)
3、开启注解扫描所要使用注解的类的包名
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd ">
<!-- base-package即为所要添加注解的类中的包名 -->
<context:component-scan base-package="po"></context:component-scan>
</beans>
在javabean类上使用@Component(“id名”)
@Service(“id名”) service层
@Controller(“id名”) web层
@Repository(“id名”) dao层
使用注解配置
@Autowired 自动装配 类型名字
如果不是唯一的 可以使用@Qualifier(value=“xxx”)
@Nullable 字段上标记后可以为空
@Resource 自动装配先名字再类型
如果要开启注解 首先要在开头引入spring的约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
并且还要在xml中写
<context:annotation-config/>
直接开启注解配置完整
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd ">
<!-- 指定扫描com.fei.bean包下的所有类中的注解 -->
<context:component-scan base-package="po"></context:component-scan>
</beans>
AOP
接下来,我们先看一个极简的例子:所有的get请求被调用前在控制台输出一句"get请求的advice触发了"。
具体实现如下:
创建一个AOP切面类,只要在类上加个 @Aspect 注解即可。@Aspect 注解用来描述一个切面类,定义切面类的时候需要打上这个注解。
@Component 注解将该类交给 Spring 来管理。在这个类里实现advice:
package com.mu.demo.advice;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAdvice {
// 定义一个切点:所有被GetMapping注解修饰的方法会织入advice
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
private void logAdvicePointcut() {}
// Before表示logAdvice将在目标方法执行前执行
@Before("logAdvicePointcut()")
public void logAdvice(){
// 这里只是一个示例,你可以写任何处理逻辑
System.out.println("get请求的advice触发了");
}
}
创建一个接口类,内部创建一个get请求:
package com.mu.demo.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/aop")
public class AopController {
@GetMapping(value = "/getTest")
public JSONObject aopTest() {
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
@PostMapping(value = "/postTest")
public JSONObject aopTest2(@RequestParam("id") String id) {
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
}
项目启动后,请求http://localhost:8085/aop/getTest接口:
##完全注解开发
首先我们先创建一个SpringConfig类
public class SpringConfig {
}
因为我们要让他变成配置文件所以要在类的头上进行注解配置@Configuration可以代替xml配置文件
如果我们需要让这个配置文件开启注解配置 只需要在类上加一个注解@ComponentScan(basePackages={“com”})
参数为basePackages就写需要扫描的类的包
Spring AOP
首先我们创建要切面的类 一般都是操作数据库增删改查等等
package com.dao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
/**
* @author Mr.Wang
* @version 1.0
* @date 2020-12-01 20:06
* @page com.dao
*/
@Component
@Repository
public class UserDao {
public void addUser () {
System.out.println("添加用户");
}
public void deleteUser(){
System.out.println("删除了一个用户");
}
}
我们要把他添加到容器中所以要加 注解@Component 因为他是dao层 所以也要添加@Repository
然后我们创建增强的类
package com.dao.proxy;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author Mr.Wang
* @version 1.0
* @date 2020-12-01 20:53
* @page com.dao.proxy
*/
//增强的类
@Component
@Aspect
public class UserProxy {
@Before("execution(* com..*.*(..))")
public void beforeLog(){
System.out.println("before方法被执行了");
}
}
也需要添加到容器中 添加注解@Component 由于我们这是需要切入点 我们也要添加@Aspect
其中写的beforeLog()为方法前执行 需要加注解@Before
后面跟随的(“execution(* com….(…))”)是指定哪一些方法底下才需要被执行 属于execution表达式 详细参数什么可以参考百度
其中有5种通知
package com.dao.proxy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author Mr.Wang
* @version 1.0
* @date 2020-12-01 20:53
* @page com.dao.proxy
*/
//增强的类
@Component
@Aspect
public class UserProxy {
/**
* 方法前执行
*/
@Before("execution(* com..*.*(..))")
public void beforeLog(){
System.out.println("before方法被执行了");
}
/**
* 方法后执行
*/
@After("execution(* com..*.*(..))")
public void afterLog(){
System.out.println("after方法被执行了");
}
/**
* 环绕方法执行 在前面后面都会执行 一般都有一个参数ProceedingJoinPoint
*/
@Around("execution(* com..*.*(..))")
public void aroundLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("around方法前执行了");
proceedingJoinPoint.proceed();
System.out.println("around方法后执行了");
}
//在返回值后执行
@AfterReturning("execution(* com..*.*(..))")
public void afterReturningLog(){
System.out.println("afterReturningLog方法被执行了");
}
/*
*出现异常时候执行
*/
@AfterThrowing("execution(* com..*.*(..))")
public void afterThrowingLog(){
System.out.println("afterThrowingLog方法被执行了");
}
}
公共切入点抽取 后面表达式相同 可以重用切入点的定义
@Pointcut("execution(* com..*.*(..))")
public void pointdemo(){
}
/**
* 方法前执行
*/
@Before("pointdemo()")
public void beforeLog(){
System.out.println("before方法被执行了");
}
可以自定义一个方法进行抽取 这样修改一个就可以改完所有的切入点
如果需要对同一个方法都需要进行增强 我们可以在类上添加一个注解@Order(1)后面的值可以指定优先值 越小越先执行