Lesson2:Spring更简单的读取和存储对象(使用注解)

目录

一、引言

二、存储Bean对象

2.1 准备工作

2.2 添加注解存储Bean对象

2.2.1 @Controller(控制器存储)

2.2.2 @Service(服务存储)

2.2.3 @Repository(仓库存储)

2.2.4 @Component(组件存储)

2.2.5 @Configuration(配置存储)

2.3 为什么需要这么多类注解

2.4 五大类注解的关系

2.5 Bean的命名

2.6 方法注解@Bean

 三、获取Bean对象

3.1 使用@Autowired

3.1.1 使用属性注入的方式获得对象

3.1.2 使用构造方法进行注入

3.1.3 setter注入

3.1.4 三种方法的比较

3.2 @Resource注入

3.3 @Resource和@Autowired区别

3.4 一个对象类型被Spring注入多个的解决方案

3.4.1 @Resource(name="")

3.4.2 @Autowired+@Qualifier

四、总结


一、引言

在上篇博客中,我们可以实现Spring读取和存储对象的方法。但是在操作的过程中,我们需要在spring.xml当中添加一行bean的注册内容才行,如下图所示:

我们可以发现,才用这种方式存储或者读取对象并没有想象中那么简单。

在Spring中,要想更简单的存储和读取对象的核心是使用注解。接下来将会介绍如何使用Spring的相关注解来存储和读取对象。

二、存储Bean对象

2.1 准备工作

要想将对象成功的存储到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">
    <!-- 配置一下:bean注解扫描的根路径(方面后面更简单存储对象到spring容器)-->
    <content:component-scan base-package="service"></content:component-scan>
</beans>

base-package的属性就是组建的扫描路径。

2.2 添加注解存储Bean对象

类注解:@controller @Service @Repository @Component@Configuration

方法注解:@Bean

2.2.1 @Controller(控制器存储)

使用@Controller存储bean的代码:

package service;

import org.springframework.stereotype.Controller;

@Controller //这个注解的作用,告诉Spring在启动的时候将当前对象存储到容器中,相当于<bean id="user1" class="service.UserController"></bean>
public class UserController {
    public void sayhello(){
        System.out.println("hello control");
    }
}

获取bean的代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserController;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = applicationContext.getBean("userController", UserController.class);
        userController.sayhello();
    }
}

getBean方法中的第一个参数是bean的ID,一般情况下,使用注解bean的id为类名首字母小写。

2.2.2 @Service(服务存储)

使用@Service存储bean的代码:

package service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void sayhello(){
        System.out.println("hello service");
    }
}

获取bean的代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserService userService= applicationContext.getBean("userService", UserService.class);
        userService.sayhello();

    }
}

 2.2.3 @Repository(仓库存储)

使用@Repository存储bean的代码:

package service;

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    public void sayhello(){
        System.out.println("hello repository");
    }
}

获取bean的代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserRepository;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserRepository userRepository = applicationContext.getBean("userRepository",UserRepository.class);
        userRepository.sayhello();

    }
}

 2.2.4 @Component(组件存储)

使用@Component存储bean的代码:

package service;

import org.springframework.stereotype.Component;

@Component
public class UserComponent {
    public void sayhello(){
        System.out.println("hello component");
    }
}

获取bean的代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserComponent;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserComponent userComponent= applicationContext.getBean("userComponent",UserComponent.class);
        userComponent.sayhello();

    }
}

 2.2.5 @Configuration(配置存储)

使用@Configuration存储bean的代码:

package service;

import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfiguration {
    public void sayhello(){
        System.out.println("hello configuration");
    }
}

获取bean的代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserConfiguration;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserConfiguration userConfiguration= applicationContext.getBean("userConfiguration", UserConfiguration.class);
        userConfiguration.sayhello();

    }
}

2.3 为什么需要这么多类注解

不同的类注解,用途不同。

@Controller :业务逻辑层。验证前端参数是否合法。

@Service:服务层。数据的组装和调用数据库接口的管理。

@Repository:数据持久层。数据库的查询和管理。

@Configuration:配置层。设置当前项目中所有配置信息。

@Component:实体类。

2.4 五大类注解的关系

看 @Controller 、@Service 、 @Repository 、 @Configuration 等注解的源码,可以发现这些注解都是@Component 的“⼦类”。

2.5 Bean的命名

使用标准的大驼峰命名:读取的时候⾸字⺟小写就可以获取到 bean 了。

如果是前两个字母都是大写:读取的时候就不用变,直接用。

package service;

import org.springframework.context.annotation.Configuration;

@Configuration
public class USer {
    public void sayhello(){
        System.out.println("hello USer");
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.USer;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        USer uSer= applicationContext.getBean("USer", USer.class);
        uSer.sayhello();
    }
}

2.6 方法注解@Bean

将当前方法返回的对象存入到Spring。

注意:

@Bean必须配合类注解一起使用。原因:出于对性能的考量因为扫描所有方法的返回值是否需要将其存储在Spring中,代价很会很大。因此,只扫描类注解+@Bean来实现对象的托管

package service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserBean {
    @Bean
    public UserInform getUser(){
        UserInform userInform = new UserInform();
        userInform.setId(1);
        userInform.setName("小明");
        return userInform;
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserInform;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserInform userInform = applicationContext.getBean("getUser", UserInform.class);
        System.out.println(userInform);
    }
}

②@Bean重命名

可以给当前对象指定多个名称,使用多个名称获取的对象都是同一个

@Bean重命名后使用原方法名就不能得到对象了

name={} 可以省略,可以写为@Bean({"user1","userInfo1"})

package service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserBean {
    @Bean(name = {"user1","userInfo1"})
    public UserInform getUser(){
        UserInform userInform = new UserInform();
        userInform.setId(1);
        userInform.setName("小明");
        return userInform;
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserInform;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserInform userInform = applicationContext.getBean("user1", UserInform.class);
        UserInform userInform2 = applicationContext.getBean("userInfo1", UserInform.class);
        System.out.println(userInform);
        System.out.println(userInform2);
    }
}

 三、获取Bean对象

获取Bean对象也称为对象装配,是把对象取出来放到某个类中,也成为对象注入。

3.1 使用@Autowired

3.1.1 使用属性注入的方式获得对象

先将BookService对象存入到Spring中,再将对象从容器中拿出来。

package injectiontry.Service;

import org.springframework.stereotype.Service;

@Service  //将BookService存入Spring中
public class BookService {
    public void addBook(int bookId,String bookName){
        System.out.println("书的信息是"+bookName+bookId);
    }
}
package injectiontry.Controller;

import injectiontry.Service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class BookController {
    // 通过属性注入的方式获得对象
    @Autowired
    private BookService bookService;

    public void showBook(){
        bookService.addBook(1,"三国");
    }
}
import injectiontry.Controller.BookController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        BookController bookController = applicationContext.getBean("bookController",BookController.class);
        bookController.showBook();
    }
}

先使用类型进行查询,如果在Spring中查询到了同类型的对象就直接返回。否则使用类名称进行查询,如果两个都查询不到,那么注入失败,否则就为成功。

3.1.2 使用构造方法进行注入

    private BookService bookService;
    @Autowired
    public BookController(BookService bookService){
        this.bookService = bookService;
    }

当类中只有一个构造方法时,@Autowired可以省略掉,当有多个构造函数时,@Autowired不能省略。

3.1.3 setter注入

    @Autowired
    public void getBookService(BookService bookService){
        this.bookService = bookService;
    }

3.1.4 三种方法的比较

属性注入的写法最简单,缺点:这种写法只适应于IoC容器,非IoC容器不能识别。

构造方法注入,是官方推荐的首选方案。缺点:代码比较多,看起来比较臃肿。优点是通用性比较好,代码的移植性比较高。

setter注入。通用性也比较好。是早期Spring推荐的注入方式。

3.2 @Resource注入

    private BookService bookService;
    @Resource
    public void getBookService(BookService bookService){
        this.bookService = bookService;
    }

3.3 @Resource和@Autowired区别

出身不同:@Autowired来自Spring框架,@Resource来自JDK。

设置的参数不同:使用@Autowired可以设置的属性只有一个,而@Resource却有多个。

修饰对象不同:@Autowired可以用于属性注入、构造方法注入和Setter注入。而@Resource只能用在属性注入和setter注入,不能用于构造方法注入。

3.4 一个对象类型被Spring注入多个的解决方案

3.4.1 @Resource(name="")

在Spring中注入了两个UserInform对象,可以通过 @Resource(name="")就可以获得。

package asd;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserBean {

    @Bean({"user1"})
    public UserInform getUser1(){
        UserInform userInform = new UserInform();
        userInform.setId(1);
        userInform.setName("小明");
        return userInform;
    }
    @Bean({"user2"})
    public UserInform getUser2(){
        UserInform userInform = new UserInform();
        userInform.setId(2);
        userInform.setName("小王");
        return userInform;
    }
}
package asd;

import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class USer {
    @Resource(name = "user2")
    private UserInform userInform;
    public void showUser(){
        System.out.println(userInform);
    }
}

3.4.2 @Autowired+@Qualifier

package asd;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class USer {
    @Autowired
    @Qualifier("user1")
    private UserInform userInform;
    public void showUser(){
        System.out.println(userInform);
    }
}

四、总结

将对象存储到Spring中:

①存储bean对象的注解有5种:@Controller、@Service、@Repository、@Component、@Configuration。不同的类注解,用途不同。@controller负责业务逻辑层。验证前端参数是否合法。@Service是服务层,用于数据的组装和数据库接口的管理。@Repository是数据持久层。用于数据库的查询和管理。@Configuration是配置层。用于设置当前项目中所有的配置信息。@Component主要包含了一些实体类。其他四种注解都是@Component的子类。

②方法注解@Bean。出于对性能的考量,方法注解必须和类注解一起使用。方法注解支持重命名。可以给该方法返回的对象指定多个名称。

将对象从Spring中拿出:

使用@Autowired:可以用于属性注入、构造方法注入、和setter注入

使用@Resource:属性注入和setter注入

当同一个类型的对象被Spring多次注入,如何获取?

way1:@Resource(name="")    way2:@Autowired+@Qualifier

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘减减

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值