Spring
核心功能为IOC、DI、AOP
IOC:控制反转,将创建对象的过程交由Spring完成,以及对象的生命周期管理过程交由Spring完成。
DI:依赖,将对象之间的关系直接注入(不需要创建对象而是直接使用),设置对象之间的关联关系。依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
AOP:面向切面编程,补充面向对象编程的不足。
IOC
IOC实现(XML方式)
- 创建类 ```java package cn.tedu.controller;
public class Test { public void get() { System.out.println(“Test Hello”); } }
2. 创建配置文件<br />配置bean的信息<br />id为bean的唯一标识,<br />class为类的全路径
```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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
配置bean的信息
id为bean的唯一标识,
class为类的全路径
-->
<bean id="Test" class="cn.tedu.controller.Test"></bean>
</beans>
- 测试
- 读取配置文件
- 直接调用
getBean()
方法 ```java package cn.tedu.test;
import cn.tedu.controller.Hello; import org.junit.jupiter.api.Test; import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
public class Test1 { @Test public void get(){ //1.读取配置文件 ClassPathXmlApplicationContext springIOC = new ClassPathXmlApplicationContext(“spring-config.xml”);
//2.getBean,参数为id,唯一标识
Hello test = (Hello) springIOC.getBean("hello");
System.out.println(test);
test.get();
}
}
<a name="tWSlz"></a>
### IOC实现(注解方式)
1. 创建类<br />需要在类上使用`@Component`注解<br />spring提供,用于IOC的注解
1. `@Component`
1. `@Controller`
1. `@Service`
<br />`@Component`注解可以指定名称
```java
@Component//自动完成IOC-->{"User","new User()"},User为类名,为默认名称
@Component("a")//自己指定名字a->{"a","new User()"}
package cn.tedu.controller;
import org.springframework.stereotype.Component;
/*
spring提供用于IOC
*/
@Component
public class User {
public void test() {
System.out.println("我乃马钊,孽畜还不现出原形!");
}
}
创建配置文件
配置包扫描使用base-package
指定包的路径名<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置包扫描
base-package 指定包的路径名
-->
<context:component-scan base-package="cn.tedu.controller"/>
</beans>
测试
- 读取配置文件
- 获取注解的bean,其中
getBean()
方法中的参数为类名,类名首字母需小写。 ```java package cn.tedu.test;
import cn.tedu.controller.Hello; import cn.tedu.controller.User; import org.junit.jupiter.api.Test; import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
public class Test1 { @Test public void get() { //1.读取配置文件 ClassPathXmlApplicationContext springIOC = new ClassPathXmlApplicationContext(“spring-config.xml”);
//2.获取注解的bean
User user = (User) springIOC.getBean("user");
System.out.println(user);
}
}
<a name="jLn0o"></a>
## DI依赖注入
<a name="pqUMi"></a>
### 普通方式
1. 创建类<br />Dept部门类 <br />Emp员工类
```java
package cn.tedu.di;
public class Dept {
String name = "卫生清洁部";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "部门:{" +
"name='" + name + '\'' +
'}';
}
}
package cn.tedu.di;
public class Emp {
String name = "马钊";
/*
绑定两个类之间的关系
*/
private Dept d;
public Dept getD() {
return d;
}
public void setD(Dept d) {
this.d = d;
}
@Override
public String toString() {
return "Emp{" +
"姓名='" + name + '\'' +
"," + d +
'}';
}
}
- 创建对象,建立关系 ```java package cn.tedu.test;
import cn.tedu.di.Dept; import cn.tedu.di.Emp;
public class Test { @org.junit.jupiter.api.Test public void test() { Dept dept = new Dept();
Emp emp = new Emp();
System.out.println(emp);
emp.setD(dept);
System.out.println(emp.getD());
System.out.println(emp);
dept.setName("垃圾处理部");
System.out.println(emp);
}
}
<a name="vfNO8"></a>
### 使用spring自动注入依赖
1. 创建类<br />student类
```java
package cn.tedu.person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Student {
String name = "孔子";
@Autowired//注入依赖
Teacher teacher;
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "{" +
"student=" + name +
",teacher=" + teacher +
'}';
}
}
teacher类
package cn.tedu.person;
import org.springframework.stereotype.Component;
@Component
public class Teacher {
String name = "老子";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
创建配置文件
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.tedu.person"/>
</beans>
测试 ```java package cn.tedu.test;
import cn.tedu.person.Student; import cn.tedu.person.Teacher; import org.junit.jupiter.api.Test; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 { @Test public void test() { ClassPathXmlApplicationContext springIOC = new ClassPathXmlApplicationContext(“spring-DI.xml”);
Object o = springIOC.getBean("student");
System.out.println(o);//直接将两个类之间的依赖关系输出
/*
普通方式
Student student = (Student) springIOC.getBean("student");
Teacher teacher = (Teacher) springIOC.getBean("teacher");
student.setTeacher(teacher);
System.out.println(student);
teacher.setName("郯子");
System.out.println(student);
*/
}
}
<a name="d6FoN"></a>
## AOP面向切面编程
<a name="TzMNg"></a>
### 概述
AOP时一种编程思想,面向切面编程,补充了面向对象编程(OOP)的不足。本质实在执行方法前后添加功能。
使用场景:统计性能,权限管理,事务管理,日志,缓存
使用时需要导入依赖
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
AOP三要素:
- Aspect定义切面;本质为一个类。
- 通过通知(Advice)来指定具体做什么事情。如方法执行前做什么,方法执行后做什么,抛出异常做什么,从而实现对象行为(方法)的增强;本质为一个方法。
- 具体通过切点(PointCut)配置切点表达式(expression)来指定在哪些类的哪些方法上织入(ware)横切逻辑;被切的地方叫连接点(JoinPoint);指定类中哪些方法需要使用通知的功能。
专业术语
术语 | 描述 |
---|---|
切面(Aspect) | 切面泛指交叉业务逻辑。比如事务处理、日志处理就可以理解为切面。常用的切面有通知与顾问。实际就是对主业务逻辑的一种增强 |
织入(Weaving) | 织入是指将切面代码插入到目标对象的过程。 |
连接点(Joint point) | 连接点指切面可以织入的位置。 |
切入点(Pointcut) | 切入点指切面具体织入的位置。 |
通知(Advice) | 通知是切面的一种实现,可以完成简单织入功能(织入功能就是在这里完成的)。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。 |
目标对象(Target) | 被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。也称为被通知对象。 |
通知类型
通知 | 描述 |
---|---|
前置通知(before) | 在一个方法执行之前,执行通知。 |
后置通知(after) | 在一个方法执行之后,不考虑其结果,执行通知。 |
返回后通知(afterRetruning) | 在一个方法执行之后,只有在方法成功完成时,才能执行通知 |
抛出异常后通知(afterThrowing) | 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 |
环绕通知(around) | 在建议方法调用之前和之后,执行通知。 |
常用注解
@Aspect: 指定一个切面类
@PointCut: 表示一个切点
JoinPoint:作为函数的参数传入切面方法,可以得到目标方法的相关信息
通知注解
- 前置通知(@Before)
- 后置通知(@After)
- 返回通知 (@AfterReturning)
- 异常通知 (@AfterThrowing)
- 环绕通知 (@Around)
[
](https://blog.csdn.net/huweiliyi/article/details/107692925)