JAVAEE进阶|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的注册内容才行,如下图所示:
JAVAEE进阶|Lesson2(Spring更简单的读取和存储对象(使用注解))
文章图片

我们可以发现,才用这种方式存储或者读取对象并没有想象中那么简单。
在Spring中,要想更简单的存储和读取对象的核心是使用注解。接下来将会介绍如何使用Spring的相关注解来存储和读取对象。
二、存储Bean对象 2.1 准备工作 要想将对象成功的存储到Spring中,需要配置一下存储对象的扫描包路径,只有配置的包下的所有类,加了注解之后才能被正确的识别并保存到Spring中。


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在启动的时候将当前对象存储到容器中,相当于 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); } }

JAVAEE进阶|Lesson2(Spring更简单的读取和存储对象(使用注解))
文章图片

三、获取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多次注入,如何获取?
【JAVAEE进阶|Lesson2(Spring更简单的读取和存储对象(使用注解))】way1:@Resource(name="")way2:@Autowired+@Qualifier

    推荐阅读