Spring框架
文章目录
1.Spring框架概述
即是框架又是容器
-
作为容器:
利用spring的核心功能:IOC和DI,解决了各类之间复杂的依赖管理。Spring容器可以自动创建、装配和管理Java对象,使开发人员能够更加专注于业务逻辑的实现,而不需要关心对象创建(依赖管理)和生命周期的管理。
-
作为框架:
我们使用Spring框架,Spring框架提供了很多基础的与业务逻辑无关的功能,如数据访问、事务管理、依赖注入、持久化框架集成等等。我们只需要通过配置和使用Spring框架,就可以快速实现这些通用功能,从而专注于业务逻辑的实现。例如,我们可以通过Spring框架提供的JDBC模板和事务管理,来快速实现与数据库的交互和事务管理,而不需要从头开始编写所有与业务无关的车轮代码。
2.Spring框架的三个核心内容
IOC和DI是同一个东西的两个方面。
IOC(控制反转)
概念:
IoC控制反转。由容器来管理对象之间的依赖关系(而不是对象本身来管理),就叫“控制反转” 。应用**本身不负责依赖对象的创建和维护,而是由外部容器来负责。**这样控制权就由应用转移到外部容器,控制权的转移就是所谓的反转。
详细定义:当某个对象(可能是一个Java实例,调用者)需要另一个对象(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring框架里,创建被调用者的工作不再由调用者来完成,而是将别调用者的控制权(创建权,维护权)反转给了ioc容器,因此称为控制反转;
优点:
不必关心组件的创建不必管理组件的生命周期 使开发人员能够更加专注于业务逻辑的实现
spring提供的ioc容器:
BeanFactory和ApplicationContext(主要)。其在applicationcontext.xml和web.xml里配置。IoC 容器也是对象,需要实例化、提供方式使 DI 与应用程序能交互、不使用时销毁它。与BeanFactory不同的是:在构建ApplicationContext( IoC 容器)过程中, Spring会自动实例化XML中定义的各个单例。然后当我们需要使用某个Bean时,Spring容器会从容器中查找这个Bean实例,并将这个实例返回给我们
DI(依赖注入)
概念:
依赖注入可以理解成IoC的一种应用场景,当一个对象或组件需要另一个组件的依赖时,容器动态地将某种依赖关系注入到组件中。
详细:创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
优点:
Spring的DI容器降低了业务对象替换的复杂性,提高组件之间的解耦。
依赖注入的两种方式:
这里指的是,向由容器管理的bean(被依赖对象),注入属性的两种方式。
利用控制反转的思想可以将创建对象的任务交给Spring容器去执行,对象创建好了以后,自然就要去考虑如何给我们的对象赋值的问题,Spring分别基于xml文件和注解解决了给对象赋值的问题,这就相当于给类的私有属性暴露出两种公共访问方法供人进行属性设置一样。
基于XML的依赖注入的两种方式(在有了下面的springboot的注解方法依赖注入后,就不推荐用这个了)
- 设值注入:指通过setter方法传入被调用者的实例。
在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法。
bean有提供属性对应的set方法:
public class Chinese implements Person {
private Axe axe;
public Axe getAxe() {
return axe;
}
public void setAxe(Axe axe) { //有set设值方法,如果这里的设值只是单纯的bean自己的属性,不涉及到依赖注入(DI)的思想 //而这里的set的属性是将另一个bean引用进来成为属性值
this.axe = axe;
}
public void useAxe() {
axe.chop();
}
}
其在applicationcontext.xml中的设置:
1. <bean id="chinese"
class="org.spring.Chinese">
2. <property name="axe">
3. <ref bean="stoneAxe" /> //用ref标签注入了被依赖bean也是它这里的属性:axe。
4. </property> stoneAxe就是Axe类型的另一个Bean的ID.因为是在属性property标签中设的,
5. </bean> 所以又叫:属性注入
//<property>标签中的value属性可以为Bean设置单纯的属性值,这种方式并不涉及到依赖注入(DI)的思想。而依赖注入通常是通过将其他Bean的引用作为当前Bean的属性值.
//<ref>标签用来注入其他Bean的引用作为当前Bean的属性值。使用<ref>标744签,可以将其他Bean的引用作为当前Bean的属性值,从而实现Bean之间的依赖注入。
- 构造注入:指通过构造函数来完成依赖关系的设定,而不是通过setter方法。
public class American implements Person {
private Axe axe;
public American(Axe axe){
this.axe = axe;
}
public void useAxe() {
axe.chop();
}
}
1. <bean id="american"
class="org.spring.American“>
2. <constructor-arg> //<constructor-arg>标签用于配置Bean的构造函数参数
3. <ref bean="steelAxe" /> //<constructor-arg>标签中使用了<ref>标签,将Bean ID为steelAxe的Bean 4. </constructor-arg> 作为构造函数的参数传入到American类的构造函数中进行实例化。
5. </bean>
基于注解的DI实现
在Spring Boot中,默认使用基于注解的依赖注入方式,不需要使用XML配置文件来定义Bean。我们可以通过在类上使用注解(如@Component
、@Service
等)来将一个类声明为Bean,同时使用@Autowired
注解来自动注入依赖对象。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
// ...
}
@Service
注解表示将UserServiceImpl
类声明为一个Service Bean,而@Autowired
注解表示自动注入一个UserDao
对象。
AOP面向切面编程
AOP概念
-
AOP面向切面编程,AOP将应用系统分为两部分,核心业务逻辑及横向的通用逻辑,即方面(Aspect)。比如大型应用中涉及的持久化管理、事务管理、安全管理、日志管理和调试管理。 使用AOP可以将处理Aspect的代码注入主程序,AOP可以防止代码混乱。
-
在实际应用中,常常会写一些与具体业务无关的代码,例如**日志、**权限、异常处理、安全、事务处理等。在编写的过程中,将这样的代码编写到一起,所以处处都有重复的代码。使用AOP,就是将这种和业务逻辑关系不大的代码分离出来,利用时动态插入各个业务中,达到重用的目的。
-
AOP思想把软件系统分为两个部分:
核心关注点 主要关注系统的业务逻辑;
横切关注点 主要关注系统级的服务,供业务逻辑使用。
AOP术语
-
切面(aspect):
切面是你要实现的交叉功能。就是通知和切入点的结合的称呼。通知和切入点共同定义了关于切面的全部内容:它的功能、在何时和何地完成功能。
-
通知(Advice):
通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题。应该在一个方法被调用之前?之后?或者抛出异常时。
-
切入点(pointcut):
如果说通知定义了切面的“什么”和“何时”,那么切入点就定义了“何地”。
-
连接点(joinpoint)连接点是应用程序执行过程中能够插入切面的地点。这些点可以是方法被调用时、异常抛出时、甚至字段被编辑时
AOP配置
基于XML的AOP配置 :
在Spring配置文件里,所有的切面和通知器都要配置在aop:config标签里。
一个applicationContext可以包含多个aop:config标签,一个aop:config可以包含pointcut、advisor、aspect元素(注意必须是这个顺序)。
3.配置文件等其他内容
核心配置文件applicationcontext.xml
定义Bean时,通常需要指定两个属性:
- id:确定该Bean的唯一性标识。Spring配置文件中定义的Bean的ID,就相当于实例化后的对象名。
- class:指定该Bean的具体实现类。另外,可以给Bean定义别名。
<?xml version="1.0" encoding="UTF-8“ ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="..." class="..."> ... </bean>
<bean id="..." class="..."> ... </bean>
...
</beans>
eg: