开发者

Spring中存对象和取对象的方式详解

目录
  • 1.存储对象(Bean)
    • 1.1配置扫描路径(重要!!!)
    • 1.2添加注解存储对象
      • 1.2.1类注解
      • 1.2.2方法注解
  • 2.取出对象
    • 2.1属性注入 
      • 2.2setters方法注入
        • 2.3构造方法注入
          • 2.4另外种注入关键字@Resource

          本文我来介绍一种更简单的存储对象方式和取对象方式,跟上我的节奏,我们开始吧!!

          透露一下:Spring中更简单的存对象与取对象的方式是注解。

          给大家插个题外话(了解即可),注解实现有两种方式:1.在编译的时候,把注解替换成相关代码,并添加到我们原来的代码中。2.拦截方法,当程序执行到某个方法时,会执行拦截,在执行之前或之后或之中进行一些操作(与我们写的注解有关)。

          1.存储对象(Bean)

          在上一篇我们存储对象是在配置文件中添加<bean>标签,但这样其实很麻烦,我们每次都得去那添加一个。所以为了简化,我们可以在配置文件中配置扫描路径,然后通过注解来存储对象。

          1.1配置扫描路径(重要!!!)

          在使用的时候,把下面这段代码放到你的配置文件中,把<content>标签中的包名替换成你项目需要扫描的包名。(这个搭配注解来实现存储对象)

          <?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">
              <content:component-scan base-package="包名"></content:component-scan>
          </beans>

          为什么会配置这个扫描路径呢?举个例子吧,假设你找个人,你是从整个中国一个一个找好找还是从一个村里找好找。所以嘛,Spring也是这样呀,你给它配置了扫描包,Spring就会从这个包里一个一个找,看哪些添加了注解(需要Spring帮忙创建对象的),他就会把哪些类存储起来。

          1.如果我们配置的扫描包中存在子类,里面的注解也是会被扫描的。

          2.如果我创建的类在扫描包外面,此时我用相关注解也没有用的,因为根本不会扫这个类!

          3.那如果我的类就是在扫描包外面,但是欸,我还是想交给Spring创建对象,肿么办呢?好说嘛!用我上一篇存储Bean的方法,扫描包可以与Bean同时生效的。

          4.我们设置了扫描包,没有添加注解,这样也是没办法将对象存储到Spring中的。(两个要搭配使用!!!)

          1.2添加注解存储对象

          将对象存储到Spring中,有两种可以实现,一种是类注解,一种是方法注解。

          1.2.1类注解

          类注解有五种:@Controller @Service @Component @Repository @Configuration。

          我先来说一下,为啥有这么多类注解。简单来说,为了让程序员看到类注解后更直观的知道这个类是干什么的。JavaEE上有标准分层(至少三层):控制层,业务层,数据层。当然也有更多层的划分,大家可以看阿里巴巴Java开发手册。

          控制层主要用于与用户交互,业务层主要用于处理一些业务,数据层主要与数据库进行交互。不同层干不同事,所以也就出来了不同的注解。

          1.2.1.1@Controller

          这个注解主要用于控制层中。代码如下:

          @Controller//通过这个注解将对象存储到Spring中
          public class StudentController {
              public void study() {
                  System.out.println("控制层aaaa");
              }
          }

          1.2.1.2@Service

          这个注解一般都是用于业务层的。

          @Service//通过这个注解存储对象
          public class StudentService {
              public void eat() {
                  System.out.println("业务层啊啊啊");
              }
          }

          1.2.1.3@Repository

          这个注解用在Dao层,也即是数据层。

          @Repository
          public class StudentMapper {
              public void study() {
                  System.out.println("我是数据层");
              }
          }

          1.2.1.4@Component

          这个用于哪呢?当我们进行一些操作不属于三层中的任何一层的时候,我们就可以用这个注解。

          @Component
          public class Test {
              public void test() {
                  System.out.println("保密功能");
              }
          }

          1.2.1.5@Configuration

          这个一般都是用于配置类上。

          @Configuration
          public class Test1 {
              public void set() {
                  System.out.println("配置类");
              }
          }

          1.2.1.6五大类注解的关系

          这五大类注解其实本质都一样,都是为了将对象存储到Spring中。并且@Controller / @Service / @Repository / @Configuration这几个的源码中都存在@Component,可以认为这四个注解均为@Component的子类,或者均为@Component的扩展。

          1.2.1.7通过类注解将对象存储到Spring中的命名规则

          1. 当我们创建的类名为比较标准的大驼峰形式,Spring提供的对象名为首字母小写,其余不动的形式。
          2. 如果类名首字母和第二个字母都为大写,提供的对象名为原类名。
          3. 除了第二条外,默认情况下都是Spring提供的对象名为首字母小写,其余不动的形式。

          1.2.2方法注解

          1.2.2.1使用与注意事项

          方法注解为@Bean。顾名思义,该注解用到方法上。

          创建一个User类,并且创建一个Users类,我们来使用一下。

          //User类
          public class User {
              private int id;
              private String name;
              private int age;
           
              public int getId() {
             BuzbnmsBad     return id;
              }
           
              public void setId(int id) {
                  this.id = id;
              }
           
              public String getName() {
                  return name;
              }
           
              public void setName(String name) {
                  this.name = name;
              }
           
              public int getAge() {
                  return age;
              }
           
              public void setAge(int age) {
                  this.age = age;
              }
          }
           
           
           
          //Users类
           
          @Component
          public class Users {
              @Bean
              public User user1() {
                  User user = new User();
                  user.setAge(18);
                  user.setName("张三");
                  user.setId(1);
                  return user;
              }
          }

          注意事项:

          1.@Bean注解必须搭配五大类注解使用,否则会报错的!(为了Spring执行的性能)

          2.通过方法注解将对象存储到Spring中命名规则为(默认情况下)对象名等于方法名。

          3.方法的返回类型必须存在,且必须为一个类。

          4.我们可能不同类却存在相同方法名的方法,此时如果我们仍采用方法名作为对象id来获取对象,此时会出现覆盖。最后只有一个结果,而且还不一定是我们想要拿到的那个对象。我们有两种方法进行解决:一种是通过注解@Order注解来给其排序,值越小的优先级越高,越先执行。(但是也会覆盖)最后呈现的结果为值最大的。另外一种是给Bean重命名。

          5.当我们对同一类型使用多个@Bean时,通过注入的方式注入对php象会报错的,因为有多个Bean了,Spring不知道用哪个了。有两种解决方法:(1)注入的时候,使用Resource注解,并且指定对象名,通过name属性;(2)使用@Qualifier注解的value属性来设置注入的名称(必须结合Autowired使用)。

          1.2.2.2Bean重命名

          由于上面我们提到了当用默认的提供名字的时候可能会出现误差,所以我们可以对方法上面的@Bean进行重命名。说白了也就是对存储到Spring种的对象指定好名字。

          //可以只指定一个名字
              
          @Bean(name = "user")//这里可以用name=...也可以用value=.....
              public User user1() {
                  User user = new User();
                  user.setAge(18);
                  user.setName("张三");
                  user.setId(1);
                  System.out.println(1);
                  return user;
              }
           
           
          //也可以指定多个名字(用哪个都可以)
           
           
          @Bean(name = {"user","use","custom"})//这里可以用name=...也可以用value=.....
              public User user1() {
                  User user = new User();
                  user.setAge(18);
                  user.setName("张三");
                  user.setId(1);
                  System.out.println(1);
                  return user;
              }

          但是,当我们重命名以后,就不可以再用方法名(Spring默认提供的名字)来取出对象了,除非你将重命名后的名字设置为了方法名。

          2.取出对象

          我在上一篇文章中,叙述了取出对象的方法,正常来说,我们仍这样去取出最终对象。但是在一些类中用到另外的类的时候,我们可以有简单方法呀,也就是对象注入。

          对象注入有三种方式:属性注入;setters方法注入;构造方法注入。

          @Autowired是先通过类型进行查找,如果发现有多个,然后通过名称(根据我们定义的属性后面,我们定义的变量名查找)查找。(装配顺序)

          @Qualifier必须php和@Autowired一起使用,@Qualifier通过名字来进行注入。

          @Resource先根据名称(如果有多个相同的名称)查再根据类型查。

          @Value注入普通类型属性。

          2.1属性注入 

          @Controller
          public class StudentController {
              @Autowired
              public StudentService studentService;//在控制类中引入了另外一个类,为了更方便使用,我们这里采用对象注入方式注入对象。
              public void study() {
                  System.out.println("控制层aaaa");
              }
          }

          BuzbnmsBad性注入就是通过@AutoWired注解来完成的。将这个注解放在当前类中引入的另外类最为成员变量的上面即可。

          优点:很简单。

          缺点:

          1.对于有final修饰的变量无法无法进行注入。

          2.兼容性差,只使用于IoC容器。

          3.风险更大,更容易违背单一设计原则。(比如在服务层,我们就想处理一套业务,但通过这个我们可以进行多套业务)

          2.2setters方法注入

          也就是通过setters方法进行注入

          @Controller
          public class StudentController {
              private StudentService studentService;
           
          //添加setter方法,并添加注解(注入对象)
          @Autowired
              public void setStudentService(StudentService studentService) {
                  this.studentService = studentService;
              }
           
           
              public void study() {
                  System.out.println("控制层aaaa");
              }
          }

          优点:符合单一设计规则,每个Setter方法只有一个参数。

          缺点:

          1.不能注入不可变对象(final修饰的)

          2.使用setter注入的对象可能被修改。

          2.3构造方法注入

          也javascript就是通过构造方法来注入对象。

          @Controller
          public class StudentController {
              private StudentService studentService;
          //通过构造方法来注入了
           
          @Autowired
              public StudentController(StudentService studentService) {
                  this.studentService = studentService;
              }
           
           
           
              public void setStudentService(StudentService studentService) {
                  this.studentService = studentService;
              }
           
              public void study() {
                  System.out.println("控制层aaaa");
              }
          }

          1.如果当前类只有这样的一个构造方法,@Autowired这个注解是可以省略的。

          优点:

          1.可以注入不可变对象(final修饰的)为什么呢?因为被final修饰的变量必须被复制,要不直接复制,要不就是在构造方法中复制。

          2.注入对象不会被改变的,构造方法只会执行一次。

          3.构造方法注入可以保证完全被初始化。

          4.通用性更好。

          2.4另外种注入关键字@Resource

          和@Autowired相同之处:

          • 都是进行注入。

          不同之处:

          • @Autowired来自Spring而@Resource来自JDK
          • 与@Autowired相比,@Resource支持更多参数,我们可以设置name等于什么,根据名称注入Bean。
          • @Autowired可以用于三种注入方式中,而@Resource只可以用在Setter和属性注入中。

          以上就是Spring中存对象和取对象的方式详解的详细内容,更多关于Spring存对象和取对象的资料请关注编程客栈(www.devze.com)其它相关文章!

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜