SpringIOC以及AOP注解开发

和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。
本质上:所有一切的操作都是 Java 代码来完成的,XML 和注解只是告诉框架中的 Java 代码如何执行。

 

 

 新建一个maven项目

 Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。

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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>spring-aop</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-aop</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
      <!--这里是设置作用域-->
      <!--注释作用域,表明我想让它为全局使用-->
      <!--<scope>provided</scope>-->
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>
  </dependencies>
</project>

注解开发的话当然需要配置类

@Configuration //这个类就是配置类相当于配置文件

@ComponentScan 

用于类或接口上主要是指定扫描路径,spring会把指定路径下带有指定注解的类自动装配到bean容器里。会被自动装配的注解包括@Controller、@Service、@Component、@Repository等等。与ComponentScan注解相对应的XML配置就是<context:component-scan/>, 根据指定的配置自动扫描package,将符合条件的组件加入到IOC容器中;

@EnableAspectJAutoProxy

 

 

 

 

package lps.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @author 阿水
 * @create 2023-02-23 14:52
 */
@Configuration
@ComponentScan({"lps"})
@EnableAspectJAutoProxy
public class SpringConfig {
}

①使用@Component注解标记的普通组

 

 

 

 ②使用@Controller注解标记的控制器组件

③使用@Service注解标记的业务逻辑组件

④使用@Repository注解标记的持久化层组件

 

 

 

通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。
对于Spring使用IOC容器管理这些组件来说没有区别,也就是语法层面没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用。
注意:虽然它们本质上一样,但是为了代码的可读性,为了程序结构严谨我们肯定不能随便胡乱标记。

 

 

 

 

@Autowired和@Resource区别

提供方不同

​ @Autowired 是Spring提供的,@Resource 是J2EE提供的。

装配时默认类型不同

​ @Autowired只按type装配,@Resource默认是按name装配。

 

 

 

 

 

 

 

 

切入点表达式的写法-execution函数

关键字:execution(表达式)

表达式:访问修饰符 返回值 包名.包名.包名...类名.方法名

规则表达式示例
匹配所有类的public方法 execution(public **(..))  
匹配指定包下所有类的方法(不包含子包) execution(* 包名.*(..)) execution(* test.aop.t1.*(..))
匹配指定包下所有类的方法(包含子包) execution(* 包名.**(..)) execution(* test.aop.t1..*(..))
匹配指定类下的所有方法 execution(* 包名.类名.*(..)) execution(* test.aop.t1.UserDao.*(..))
匹配指定类下的指定方法 execution(* 包名.类名.方法名(..)) execution(* test.aop.t1.UserDao.add(..))
匹配实现指定接口的所有类的方法 execution(* 包名.接口名+*(..)) execution(* test.aop.t1.UserDao+*(..))
匹配所有名称以save开头的方法 execution(* save*(..))  

Spring中的通知

Spring中一共有5种通知

前置通知(before)、后置通知(returning)、异常通知(throwing)、最终通知(after)、环绕通知(around)
复制代码
通知类型作用应用场景
前置通知 在目标方法执行前增强代码逻辑 权限控制(权限不足抛出异常)、记录方法调用信息日志
后置通知 在目标方法运行后返回值后再增强代码逻辑,在出现异常时不执行 与业务相关的,如银行在存取款结束后的发送短信消息 */
异常通知 目标代码出现异常,通知执行。记录异常日志、通知管理员(短信、邮件) 处理异常(一般不可预知),记录日志
最终通知 不管目标方法是否发生异常,最终通知都会执行(类似于finally代码功能) 释放资源 (关闭文件、 关闭数据库连接、 网络连接、 释放内存对象 )
环绕通知 目标方法执行前后,都进行增强(控制目标方法执行) 日志、缓存、权限、性能监控、事务管理

 

 

UserService.java
package lps.service;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

/**
 * @author 阿水
 * @create 2023-02-23 14:50
 */
@Service("userService")
public class UserService {
 /*   public void sing(){
        System.out.println("我爱唱歌");
    }
    public void dance(){
        System.out.println("我爱跳舞");
    }
    public void rap() {
        //int i=10/0;
        System.out.println("我爱rap 篮球 起~");
    }*/
    public void doSum(){
        long sum=0;
        for (long i = 0; i < 1000000000; i++) {
            sum+=i;
        }
        System.out.println(sum);
    }
}

Aspect代码块

package lps.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author 阿水
 * @create 2023-02-23 15:18
 */
@Component
@Aspect
public class LoggerAspect {
    //@Pointcut("execution(public * lps.service.*.*(..))")
    @Pointcut("execution(* lps.*.*.*(..))")
    private void pointcut() {
    }

   /* @AfterReturning("pointcut()")
    public void after() {
        System.out.println("AfterReturning————————————————————你的鸡哥————————————————————");
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("Before________________________你的坤坤________________________");
    }
 *//*   @Around("pointcut()")
    public void around(){
        System.out.println("_+++++环绕的鸡哥_+++++");
    }*//*
    @AfterThrowing("pointcut()")
    public void logAfterThrowing(){
        System.out.println("AfterThrowing出错啦 赶紧回来");
    }
    @After("pointcut()")
    public void afterFinalyy() {
        System.out.println("After最终通知 ");
    }*/
    @Around("pointcut()")
    public Object test(ProceedingJoinPoint point){
        Object result=null;
        //long beginTime = System.currentTimeMillis();
        long beginTime = new Date().getTime();
    
        Object[] args = point.getArgs();

        try {
            result = point.proceed(args);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }

        //long endTime = System.currentTimeMillis();
        long endTime = new Date().getTime();
        System.out.println("一起用了"+(endTime-beginTime)+"毫秒");
        return result;

    }


}

 

测试类

package lps.demo;

import javafx.application.Application;
import lps.config.SpringConfig;
import lps.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author 阿水
 * @create 2023-02-23 14:53
 */
public class test1 {
    public static void main(String[] args) {
        ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) context.getBean("userService");
   /*     userService.sing();
        userService.dance();
        userService.rap();*/
        userService.doSum();

    }
}

 

posted @ 2023-02-23 20:31  刘品水  阅读(16)  评论(0编辑  收藏  举报