Spring: 通过注解获取Bean对象

目录

一, 属性注入

属性注入的优点:

属性注入的缺点

二. Setter注入

Setter注入的优点:

Setter注入的缺点:

三, 构造方法注入 (主流方式)

构造方法注入的优点

构造方法注入的缺点

四, @Autowired与@Resource区别


获取Bean对象也叫对象注入(对象装配), 指把对象取出来放到某个类中

实现对象注入有三种方法:

1.属性注入:                将对象注入到某个类的一个属性当中。

2.构造方法注入:        通过构造方法来将对象注入到类中。

3.Setter注入:             通过 SetXXX 系列方法将对象注入到类中。

对象注入的常用注解有两个: 一个是 @Autowired ,另外一个是 @Resource   

一, 属性注入

文章的实体类:

package Spring.demo;
import java.time.LocalDateTime;

public class Article {
    String author;
    String text;
    LocalDateTime createTime;

    public void setAuthor(String author) {
        this.author = author;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
    
    @Override
    public String toString() {
        return "Article{" +
                "author='" + author + '\'' +
                ", text='" + text + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

设置两个层,Service接收前端传递的数据, 通过属性注入到Controller中,最后再App调用Controller

Spring: 通过注解获取Bean对象_第1张图片

ArticleService类:

package Spring.demo;

import org.springframework.stereotype.Service;

import java.time.LocalDateTime;


@Service
public class ArticleService {

    public Article getArticle(){

        // 伪代码,假装这是从前端获取到的数据,实际开发不会这样写
        Article article = new Article();
        article.setAuthor("李大牛");
        article.setText("锄禾日当午,飞流直下三千尺");
        article.setCreateTime(LocalDateTime.now());
        return article;
    }

}

ArticleController类:

package Spring.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Controller;

import java.time.LocalDateTime;


@Controller
public class ArticleController {

    //  通过属性注入
    @Autowired
    private ArticleService articleService;

    public Article getArticle(){
        return articleService.getArticle();
    }

}

启动类获取Bean:

import Spring.demo.Article;
import Spring.demo.ArticleController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1.先得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        ArticleController articleController = context.getBean(ArticleController.class);

        System.out.println(articleController.getArticle().toString());

    }
}

这就是属性注入

Spring: 通过注解获取Bean对象_第2张图片

然后在启动类就可以直接通过 articleController调用到toString方法

Spring: 通过注解获取Bean对象_第3张图片

Spring: 通过注解获取Bean对象_第4张图片

属性注入的优点:

实现简单,使用简单.  只需要在使用的变量前加上一个注解@Autowired 就可以在不new对象的情况下,直接获得注入的对象

属性注入的缺点

1.功能性问题:        无法注入不可变的对象(fina修饰的对象)

2.通用性问题:        只适用于IoC容器

3.违背单一设计原则:        更容易违背单一设计原则

功能性问题:

Spring: 通过注解获取Bean对象_第5张图片

在Java语法规范中,要求final修饰的对象要么直接赋值,要么在构造方法中赋值

因此 当我们用属性注入来注入final对象时,就会报错

通用性问题: 

使用属性注入的方式只适用于IoC框架,,如果将这段代码移植到其他框架上,这段代码就失效了

违背单一设计原则: 

单一设计原则: 一个类或接口,只对应一种功能

因为属性注入的方式简单,因此容易被滥用,导致一些不必要的对象被注入,更容易违背单一设计原则

但在日常开发中,有时往往需要在 单一设计原则 与 性能 之间做出取舍,比如在某些前后端交互频繁的场景,将多个接口整合成一个接口,一次性发送数据,一次性接收数据,这样就可以有效减少网络连接的TCP请求次数,显著提升了性能,但这样就违背了单一设计原则,在后期的维护与升级上就会比较麻烦.

二. Setter注入

package Spring.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Controller;

import java.time.LocalDateTime;


@Controller
public class ArticleController {

    private ArticleService articleService;
    //  通过Setter注入  (把ArticleService对象注入给ArticleController)
    @Autowired
    public void setArticleService(ArticleService articleService){
        this.articleService = articleService;
    }

    public Article getArticle(){
        return articleService.getArticle();
    }

}

Spring: 通过注解获取Bean对象_第6张图片

只需要修改这部分代码即可,在启动类运行,可以获取到Bean对象

Setter注入的优点:

通常Setter只set的一个属性,因此比较符合单一设计原则

Setter注入的缺点:

1.同样无法解决 final对象无法注入的问题

2.注入对象可被修改

Setter 注入提供了 setXXX 的方法,意味着你可以在任何时候、在任何地方,通过调用 setXXX 的方法来改变注入对象,所以 Setter 注入的问题是,被注入的对象可能随时被修改

三, 构造方法注入 (主流方式)

package Spring.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Controller;

import java.time.LocalDateTime;


@Controller
public class ArticleController {

    private ArticleService articleService;

    @Autowired
    public ArticleController(ArticleService articleService){
        this.articleService = articleService;
    }

    public Article getArticle(){
        return articleService.getArticle();
    }

}

Spring: 通过注解获取Bean对象_第7张图片

这就是构造方法注入的写法,只改动了这一部分的代码

如果当前类中只存在一个构造方法时,@Autowired也可以省略

构造方法注入的优点

构造方法注入相比于前两种注入方法,它可以注入不可变对象,并且它只会执行一次,也不存在像 Setter 注入那样,被注入的对象随时被修改的情况,它的优点有以下 4 个:

  1. 可注入不可变对象;
  2. 注入对象不会被修改;
  3. 注入对象会被完全初始化;
  4. 通用性更好。

可注入不可变对象

Spring: 通过注解获取Bean对象_第8张图片

注入对象不会被修改

构造方法注入不会像 Setter 注入那样,构造方法在对象创建时只会执行一次,因此它不存在注入对象被随时(调用)修改的情况。

注入对象会被完全初始化

因为依赖对象是在构造方法中执行的,而构造方法是在对象创建之初执行的,因此被注入的对象在使用之前,会被完全初始化,这也是构造方法注入的优点之一。

通用性更好

可以适用于任何环境,无论是 IoC框架 还是 非IoC框架

构造方法注入的缺点

1.没有属性注入简单

2.是构造方法注入,无法解决循环依赖的问题

四, @Autowired与@Resource区别

Spring: 通过注解获取Bean对象_第9张图片

你可能感兴趣的:(JavaWeb,spring,java,后端)