Spring注解和AOP

步骤:
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)后面的值可以指定优先值 越小越先执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值