最详细的一篇讲解Spring的博客

一:什么是Spring,IoC,DI

Spring是包含了众多工具方法的IoC容器。既然是Ioc容器就包含了两个最核心最基础的概念。
最核心的功能就是:一是把对象存储到Spring当中,第二个就是把对象从Spring当中取出来。

IoC(Inversion of Control 控制反转),使用控制反转的思路可以实现依赖类之间的解耦,让我们不必去关心依赖类之间的具体实现和生命过程,只需要再使用它的时候把它注入进来就可以。
优点是实现类和依赖类之间的解耦。在底层依赖类发生变化的时候,无需关心它的实现。因为我们的Ioc(控制反转)把之前需要自己创建的对象交给了其它人。我们不需要关系具体的细节,需要使用的时候直接用就可以了。

DI(Dependency Injection 依赖注入)是IoC的一种具体的实现手段,指的是在程序运行的时候,动态的将对象注入到类的一种实现机制,让当前类可以使用依赖类。

IoC是一种指导思想,DI是具体实现。

二:Spring的创建与使用

1.创建Sprig项目
创建Spring项目就是使用Maven项目,添加Spring框架的依赖。

	<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

最后在Java文件下创建一个启动类,目的是为了测试 Spring 的核心功能:存对象和取对象。

public class App {
    public static void main(String[] args) {

    }
}

2.存储Bean对象

第一步:存储 Bean 对象,先创建一个Bean。

public class User {
    public void Name(String name){
        System.out.println("姓名:"+name);
    }
}

第二步:将创建的 Bean 注册到 Spring 容器中。

在 resources 文件夹下创建 Spring.xml 配置文件,Spring 配置文件的固定格式如下。

<?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">
 
</beans>

将 User 对象注册到 Spring 中,具体操作是在 中添加如下配置

<beans>
 <bean id="user" class="User"></bean>
</beans>

此处的 id 为 Bean 的标识符,后面读取到这个对象的时候会用到。
class 代表保存到 Spring 当中的那个对象。

3.从 Spring 框架中读取存储的业务对象

第一步:先要获得 Spring 上下文的对象。
我们在之前创建的 App 类的 main 方法中通过如下两种方式的代码 都可以 获取 Spring 的上下文对象

ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");

ClassPathXmlApplicationContext 属于 ApplicationContext 的子类,拥有 ApplicationContext 的所有功能,是通过 xml 的配置来获取所有的 Bean 容器的。

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("Spring.xml"));

ApplicationContext VS BeanFactory

  • 二者来自的 jar 包不同;BeanFactory 来自 spring.beans.jar;ApplicationnContext 来自 spring.context.jar 下。
  • BeanFactory 和 ApplicationContext 都是属于 Spring下的顶级接口;ApplicationContext 属于 BeanFactory 的子类,BeanFactory 的所有功能 ApplicationContext 都是拥有的,除此之外,ApplicationContext 还有对国际化支持,支持资源的访问,支持事件的传播…
  • 对于执行性能来说,ApplicationContext 是一次性加载并初始化所有的 bean 的,所以它的启动过程可能比较慢,但是后续的执行比较快;而 BeanFactory 是需要哪个类才去加载哪个类,因此 BeanFactory 占用的资源更少,启动更快,单后续的还行可能会慢一些。

第二步:获取指定的 Bean 对象的 getBean() 的三种用法

a)通过 xml 文件中的 bean 的 id 来获取。需要类型强转

User user = (User) context.getBean("user");

b)通过类型获取

User user = context.getBean(User.class);

优点是无需类型强转,缺点是对于多个对象的同一种类型的 Bean 获取会报错。

c)通过 id+类型 的方式来获取 bean

User user = context.getBean("user",User.class);

三:Sping 更简单的读取和存储对象

1.先创建一个 Maven 项目
2.添加Spring的依赖包
3.配置 Spring xml 文件 =》配置Spring 组件扫描路径(所有需要存储在 Spring 中的对象都需要放在此目录)

<?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:content="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">
    <!--配置 Spring 扫描的根路径(所有需要存储在Spring中的对象都需要放在此目录)-->
    <content:component-scan base-package="com.baidu"></content:component-scan>
</beans>

4.添加注解存储 Bean 对象
想要将对象存储在 Spring 中,有两种注解类型可以实现。

类注解及作用:@Controller【业务逻辑层(数据校验)】、@Service【业务逻辑层(数据组装)】、@Repository【数据库的交互,表的CRUD操作】、@Component【组件(公共组件/class)】、@Configuration【系统配置信息】
方法注解:@Bean

两种注解的区别与联系

  • 两种注解类型作用都是一样的,都是注册bean到Spring容器中。
  • 引用第三方库中的类需要装配到Spring容器时,则只能通过@Bean来实现
  • Spring 默认情况下是类扫描,因此如果使用的是方法注解 @Bean,那么必须要配合类注解(@Component)一起使用,才能将方法返回对象顺利存储到 Spring 中。

注意:Spring 中获得存入的对象,类的id默认的规则是将存入的类首字母小写、
方法 id 默认规则是方法名,首字母小写;@Bean 可以重命名,方便读取对象。

5.获取 Bean 对象(对象装配)

获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入。

对象注入(对象装配)的实现方法有三种

  1. 属性注入
    属性注入是使用 @Autowired 实现的
    从 Spring 中获取一个对象,并注入到当前类
	@Autowired
    private UserService userService;
  1. 构造方法注入
    构造方法注入是在类的构造方法中实现注入
	@Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    public User getUser(Integer age, String name){
        return userService.getUser(age,name);
    }
  1. Setter注入
	private UserService userService;
    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService;
    }

注意:如果当前类里面只有一个构造方法,那么 @Autowired 注解是可以被省略的(和Setter注入的不同)

6.另一种注入关键字:@Resource

它的用法和 @Autowired 类似。有属性注入和使用 Setter 两种方式,但是不能使用在构造方法上进行注入。

当出现多个 @Bean 方法注解,返回的对象是同一类型的时候。有两种解决办法

  • 使用 @Resource(name=“XXX”)
    需要给 @Bean 起别名。 例如 @Bean(name=“uesr1”) @Bean(name=“user2”)
  • 使用 @Autowired + @Qualifier(value=“user1”)

@Autowired 和 @Resource 的区别

  • @Autowired 来自 Spring 框架,而 @Resource 来自于JDK
  • 作用范围不同,使用 @Autowired 可以进行属性注入,Setter 注入,构造器注入;而 @Resource 只能进行属性注入和Setter 注入
  • 功能不同,@Resource 可以配合更多的属性进行使用,而 @Autowired 支持的属性较少,比如使用 @Resource 可以配合 name 属性进行使用,从而完成对象的别名注入。

四:Bean的作用域和生命周期

4.1 Bean作用域

Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域。Spring有 6 种作用域,
最后四种是基于 Spring MVC 有效的:

  • singleton:单例作用域(Spring默认选择该作用域)
  • prototype:原型作用域(多例作用域)
  • request:请求作用域
  • session:会话作用域
  • application:全局作用域
  • websocket:HTTP WebSocket 作用域

注意:后4种状态是 Spring MVC中的值,在普通的 Spring项目中只有前两种。

singleton

  1. 描述:该作用域下的Bean在IoC容器中只存在一个实例:获取Bean(即通过
    applicationContext.getBean等方法获取)及装配Bean(即通过@Autowired注入)都是同一
    个对象。
  2. 场景:通常无状态的Bean使用该作用域。无状态表示Bean对象的属性状态不需要更新
  3. 备注:Spring默认选择该作用域

prototype

  1. 描述:每次对该作用域下的Bean的请求都会创建新的实例:获取Bean(即通过
    applicationContext.getBean等方法获取)及装配Bean(即通过@Autowired注入)都是新的
    对象实例
  2. 场景:通常有状态的Bean使用该作用域

设置作用域注解 代码

	@Bean(name = {"u1"})
	// 直接设置值
    @Scope("prototype")
    // 使用枚举设置
    //@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public User user1(){
        User user = new User();
        user.setAge(18);
        user.setName("鲁硕");
        return user;
    }
4.2 Bean执行流程(Spring的执行流程)

1.启动Spring容器
在这里插入图片描述
2.加载Spring配置文件

在这里插入图片描述
3.加载配置文件bean,或者是根据配置文件中的组件(Bean)根路径,进行Bean对象的扫描五大类注解,如果有注解直接加载
4.加载的对象存储到Spring
5.其他需要使用Bean对象的地方就可以直接获取并使用
6.执行完之后,执行销毁操作

4.3 Bean生命周期

所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。

Bean的声明周期分为以下5大部分

  1. 实例化Bean(为Bean分配内存空间)
  2. 设置属性(Bean注入和装配)
  3. Bean初始化
    实现了各种Aware通知的方法,如BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法;
    执行BeanPostProcessor初始化前置方法
    执行@PostConstruct初始化方法,依赖注入操作之后被执行
    执行自己制定的init-method方法(如果有指定的话,在xml中设置)

    执行BeanPostProcessor初始化后置方法
  4. 使用Bean
  5. 销毁Bean
    销毁容器的各种方法,如@PreDestroy、DisposableBean接口方法、destroy-method。
@Component
public class BeanLifeComponent implements BeanNameAware {


    @Override
    public void setBeanName(String s) {
        System.out.println("执行通知"+s);
    }

    @PostConstruct
    public void PostConstructor(){
        System.out.println("执行@PostConstructor方法");
    }
    // init 和 destory方法名要和xml中的保持一致
    public void init(){
        System.out.println("执行init方法");
    }
    @PreDestroy
    public void preDestory(){
        System.out.println("执行@PreDestroy方法");
    }
    public void destory(){
        System.out.println("执行destory方法");
    }
}
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
        BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
        beanLifeComponent.preDestory();
        beanLifeComponent.destory();

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值