1 Spring 注解的使用
1 IOC 的概念
IOC(Inversion of Control):控制反转。
- 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。通俗的讲就是“将new对象的权利交给Spring,我们从Spring中获取对象使用即可”
Spring技术对 IOC 思想进行了实现
- Spring提供了一个容器,称为IOC容器,用来充当IoC思想中的“外部”
- IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI(Dependency Injection):依赖注入
- 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。
2 使用简单的案例实现注解的使用
案例的代码文件的结构:
(1)dao层:
package com.xbf.dao;public interface BookDao {void saveBook();
}
(2)service层:
package com.xbf.service;public interface BookService {void insertBook();
}
(3)其他实现类
@Configuration
:注解用于标记一个类为配置类,表示该类包含Bean的定义。
@ComponentScan
:告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。
@Configuration //标记该类为spring配置类
@ComponentScan({"com.xbf.dao","com.xbf.service"})
//如果扫描多个类,形如:
// @ComponentScan({"a", "b"})
//简单理解就是,传入一个静态数组
public class SpringConfig {}
@Componet
: 在Spring框架中,@Component注解是一个非常核心的概念,它用于将类标记为Spring容器中的一个Bean。这个注解告诉Spring,当应用启动时,需要在ApplicationContext中创建这个类的一个实例。这个过程是自动的,不需要显式编写代码来创建对象。
@Component
public class BookDaoImpl implements BookDao {@Overridepublic void saveBook() {System.out.println("我是BookDaoImpl类的saveBook()方法");}
}
@Autowired
:在Spring框架中,@Autowired注解是实现依赖注入(DI)的重要工具。它可以自动地将定义好的Bean注入到Spring容器中的其他Bean中。这个注解可以用于成员变量、方法和构造函数上,从而省去了手动编写大量的获取依赖和赋值代码。
@Component
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic void insertBook() {bookDao.saveBook();System.out.println("我是BookServiceImpl类的方法insert()");}
}
代码运行:
public class App {public static void main(String[] args) {//加载核心配置文件ClassPathXmlApplicationContext ioc = newClassPathXmlApplicationContext("Spring-Context.xml");//从ioc 容器中获取bean对象//BookDao bookDao = (BookDao) ioc.getBean("bookDao");//bookDao.addBook();// 获取 BookService 实例BookService bookService = (BookService) ioc.getBean("bookService");// 调用 BookService 的 insertBook 方法bookService.insertBook();}
}
运行结果:
2 SpringAOP 的使用
1 AOP 的基本概念
AOP(Aspect Oriented Programming):面向切面编程,一种编程范式,指导开发者如何组织程序结构
**作用:**在不惊动原始设计的基础上为其进行功能增强。
**Spring理念:**无入侵式/无侵入式
**原理:**动态代理
应用:1. 日志 2. 异常捕获、处理 3. 监控统计代码 4. 记录过程。
一些重要的概念:
- 连接点(JoinPoint):正在执行的方法,例如:update()、delete()、select()等都是连接点。
- 切入点(Pointcut):进行功能增强了的方法,例如:update()、delete()方法,select()方法没有被增强所以不是切入点,但是是连接点。
- 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法。
- 一个具体方法:com.xbf.dao包下的BookDao接口中的无形参无返回值的save方法。
- 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法。
- 通知(Advice):在切入点前后执行的操作,也就是增强的共性功能。
- 在SpringAOP中,功能最终以方法的形式呈现。
- 通知类:通知方法所在的类叫做通知类。
- 切面(Aspect):描述通知与切入点的对应关系,也就是哪些通知方法对应哪些切入点方法。
2 AOP 的案例实现
写一个计算器功能:计算加除法。并且用日志方式打印传递的参数、和结果、结束后通知用户计算完成!如果出现异常打印异常信息。完成步骤如下:
- 导入aop相关坐标
- 创建配置类进行Spring注解包扫描
- 定义业务接口与实现类
- 定义通知类,制作通知方法
- 定义切入点表达式、配置切面(绑定切入点与通知关系)
- 在配置类中开启AOP功能
案例代码的结构:
(1)导入AOP相关坐标
在 pom.xml 文件中,引入相关依赖:
<!-- Spring 框架的核心模块,提供了 Spring 上下文和依赖注入功能 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><!-- Spring 测试模块,提供了测试支持和集成 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.10.RELEASE</version></dependency><!-- AspectJ 织入器,用于支持 Spring AOP 编程模型 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- JUnit 测试框架,用于编写和运行测试用例 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
(2)创建相关类
- service 层:
接口类:
package com.xbf.service;
public interface JiSuanQi {//加法int add(int a, int b);//减法int sub(int a, int b);//乘法int mul(int a, int b);//除法int div(int a, int b);
}
实现类:
package com.xbf.service.impl;
import org.springframework.stereotype.Component;@Component
public class JiSuanQiImpl implements com.xbf.service.JiSuanQi {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int sub(int a, int b) {return a - b;}@Overridepublic int mul(int a, int b) {return a * b;}@Overridepublic int div(int a, int b) {return a / b;}
}
- 核心配置类
package com.xbf.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan({"com.xbf.service","com.xbf.advice"})
@EnableAspectJAutoProxy //开启 Spring 的 AspectJ 自动代理功能,支持 AOP
public class SpringConfig {}
- 通知类
package com.xbf.advice;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;@Component
@Aspect //通知类
public class MyAdvice {@Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))")public void pointcut(){};//1.前置通知@Before("pointcut()")public void before(JoinPoint joinPoint) {System.out.println("参数:" + Arrays.toString(joinPoint.getArgs()));System.out.println("开始计算");}//2.后置通知@After("pointcut()")public void after() {System.out.println("计算结束");}//3.返回通知@AfterReturning(value = "pointcut()", returning = "result")public void afterReturning(Object result) {System.out.println("计算结果:" + result);}//4 异常通知@AfterThrowing(value = "pointcut()", throwing = "e")public void afterThrowing(Throwable e) {System.out.println("异常:" + e.getMessage());}
}
@Pointcut 注解的解释:
@Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))")public void pointcut(){};
上式:AspectJ 切点表达式,用于定义一个切点(pointcut)。这个切点表达式指定了在哪些方法执行时应用通知。下面是对这段代码的详细解释:@Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))"):这是一个注解,用于定义一个切点。@Pointcut 注解是 AspectJ 框架中的一个特性,它允许你定义一个方法作为切点,然后在其他通知注解(如 @Before、@After、@Around 等)中引用这个切点。"execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))":这是切点表达式的具体内容。它的含义是:匹配 com.xbf.service.impl.JiSuanQiImpl 包中的任意类的任意方法,这些方法接收两个 int 类型的参数。execution 是 AspectJ 中最常用的切点指示器,用于指定方法的执行作为切点。这个切点表达式定义了一个非常具体的切点,它只匹配 JiSuanQiImpl 类中的那些接收两个 int 参数的方法。在这个切面类 MyAdvice 中,这个切点被用于四个不同的通知注解(@Before、@After、@AfterReturning、@AfterThrowing),这意味着在JiSuanQiImpl 类的这些特定方法执行之前、之后、返回结果后以及抛出异常后,都会执行相应的通知方法。
- 快速生成测试类:
JUnit是一个用于编写和运行可重复的自动化测试的开源测试框架,它是单元测试框架的xUnit架构的一个实例。JUnit主要有两个版本:JUnit 4和JUnit 5。
-
JUnit 4:这是JUnit的一个较早期版本,它支持Java 5及以上版本。JUnit 4引入了注解的使用,使得测试用例的编写更加简洁和直观
。 -
JUnit 5:这是JUnit的最新版本,它在设计上与JUnit 4相比有了重大的改进。JUnit 5的主要目标是支持现代Java开发实践,包括对Java 8及更高版本的支持。
默认会在 src/Test 目录下生成。
package com.xbf.service.impl;import com.xbf.config.SpringConfig;
import com.xbf.service.JiSuanQi;
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;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class JiSuanQiTest {@Autowiredprivate JiSuanQi jiSuanQi;@Testpublic void add() {//System.out.println("加法");System.out.println(jiSuanQi.add(2,4));}@Testpublic void sub() {System.out.println(jiSuanQi.sub(5,9));}@Testpublic void mul() {}@Testpublic void div() {//System.out.println(jiSuanQi.div(5,9));double n = jiSuanQi.div(5,9);double m = jiSuanQi.div(5,0);}
}
注解的解释:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
Java中的两个注解:用于配置JUnit测试框架与Spring框架的集成。@RunWith(SpringJUnit4ClassRunner.class):
这个注解是JUnit框架提供的,用于指定测试运行器(Runner)。
SpringJUnit4ClassRunner是Spring框架提供的一个测试运行器,它允许在JUnit测试中使用Spring的依赖注入和事务管理等功能。
通过这个注解,JUnit会自动加载Spring的应用上下文(Application Context),并在测试类中注入Spring管理的Bean。@ContextConfiguration(classes = SpringConfig.class):
这个注解也是Spring框架提供的,用于指定Spring应用上下文的配置类。
SpringConfig.class 是一个配置类,通常包含了Spring框架的各种配置,如Bean的定义、扫描包路径、数据库连接等。
通过这个注解,JUnit会在运行测试之前加载 SpringConfig 类,并根据其中的配置初始化Spring应用上下文。
这两个注解通常一起使用,确保JUnit测试能够在Spring容器的环境中运行,从而可以使用Spring的依赖注入和其他功能来测试Spring管理的组件。
在这个例子中,JiSuanQiTest 类是一个JUnit测试类,它使用了这两个注解来配置Spring环境,以便能够测试 JiSuanQi 类的功能。