JavaEE高阶---Spring 更简单的读取和存储对象

一 : 引言

经过前面的学习,我们已经可以实现基本的 Spring 读取和存储对象的操作了,但在操作的过程中我们发现读取和存储对象并没有想象中的那么“简单”,所以接下来我们要学习更加简单的操作 Bean 对象的方法 .

二 : 存储Bean对象

2.1 使用类注解

在这里插入图片描述

在这里插入图片描述

示例代码 :
在这里插入图片描述

在这里插入图片描述

运行结果 :

在这里插入图片描述

在这里插入图片描述

接下来我们对类注解进行一一验证 :

import com.component.UserComponent;
import com.configuration.UserConfiguration;
import com.controller.UserController;
import com.respository.UserRepository;
import com.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
//启动类
public class Test {
    public static void main(String[] args) {
        //1.得到Spring上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2.从Spring获取bean对象[使用注解,默认命名规则:类名首字母小写]
        UserService userService = (UserService) context.getBean("userService");
        //3.使用bean
        userService.doService();

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        userRepository.doRepository();

        UserComponent userComponent = (UserComponent) context.getBean("userComponent");
        userComponent.doComponent();

        UserConfiguration userConfiguration = (UserConfiguration) context.getBean("userConfiguration");
        userConfiguration.doConfiguration();

        UserController userController = (UserController) context.getBean("userController");
        userController.doUserController();
    }
}

代码结构基本一致 :

在这里插入图片描述
运行结果 :

在这里插入图片描述
在这里插入图片描述

Q1 : 5大类注解的关系 ?

在这里插入图片描述

@Controller、@Service、@Repository、@Configuration 都是基于@Component,它们的作用都是将Bean存储到Spring 中 .

Q2 : Bean的命名规则 ?

在这里插入图片描述

在这里插入图片描述

查看Bean命名的源码 :

在这里插入图片描述

在这里插入图片描述

2.2 使用方法注解

2.2.1 演示

在这里插入图片描述

在这里插入图片描述

方法注解Bean命名规则 :

在这里插入图片描述

2.2.2注意事项

在这里插入图片描述

2.2.3 @Bean重命名

方法一:@Bean(name="xxxxx")
package com.bean;

import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

@Controller
public class UserBean {
    @Bean(name = "computerUser")
    public User user1() {
        User user = new User();
        user.setAge(18);
        user.setName("百乔");
        return user;
    }
}
import com.model.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        //1.得到Spring上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2.从Spring获取bean对象[ 使用注解,默认命名规则:类名首字母小写 ]
        User user = (User) context.getBean("computerUser");
        //3.使用bean
        System.out.println(user);
    }
}

在这里插入图片描述

方法二:@Bean("xxxxx")
package com.bean;

import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

@Controller
public class UserBean {
    @Bean("computerUser")
    public User user1() {
        User user = new User();
        user.setAge(18);
        user.setName("百乔");
        return user;
    }
}
import com.model.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        //1.得到Spring上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2.从Spring获取bean对象[使用注解,默认命名规则:类名首字母小写]
        User user = (User) context.getBean("computerUser");
        //3.使用bean
        System.out.println(user);
    }
}

在这里插入图片描述

方法三 : @Bean("xxxx","xxxxxx")
package com.bean;

import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

@Controller
public class UserBean {
    @Bean(name = {"computerUser","blackboardUser"})
    public User user1() {
        User user = new User();
        user.setAge(18);
        user.setName("百乔");
        return user;
    }
}

import com.model.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        //1.得到Spring上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2.从Spring获取bean对象[使用注解,默认命名规则:类名首字母小写]
        User user = (User) context.getBean("blackboardUser");
        //3.使用bean
        System.out.println(user);
    }
}

在这里插入图片描述
在这里插入图片描述

三 : 获取Bean对象(依赖注入/对象装配)

在 Spring 中实现依赖注入的常见方式有以下 3 种:

  • 属性注入(Field Injection);
  • Setter 注入(Setter Injection);
  • 构造方法注入(Constructor Injection).

3.1 属性注入

属性注入是我们最熟悉,也是日常开发中使用最多的一种注入方式.
package com.controller;

import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    //1.属性注入
    @Autowired // 自动装配
    private UserService userService;

    public void doUserController() {
        System.out.println("Do UserController!");
        userService.doService();
    }
}

import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test3 {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.doUserController();
    }
}

在这里插入图片描述

在这里插入图片描述

3.2 Setter注入

package com.controller;

import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    //2.Setter注入
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void doUserController() {
        System.out.println("Do UserController!");
        userService.doService();
    }
}

import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test3 {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.doUserController();
    }
}

在这里插入图片描述

在这里插入图片描述

3.3 构造方法注入

package com.controller;

import com.model.User;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    //3.构造方法注入
      private  UserService userService;
	  
	  @Autowired
      public UserController(UserService userService) {
          this.userService = userService;
      }

    public void doUserController() {
        System.out.println("Do UserController!");
        userService.doService();
    }
}

import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test3 {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.doUserController();
    }
}

在这里插入图片描述

以下是关于构造方法注入的一些注意事项 :

1.当当前类只有一个构造方法时,@Autowired可以省略;当存在多个构造方法时,@Autowired注解不能省略.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.可以在一个构造方法里注入多个Autowired对象,且当仅有1个构造方法时,@Autowired可以省略.

package com.controller;

import com.configuration.UserConfiguration;
import com.model.User;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    //3.构造方法注入
      private UserService userService;
      private UserConfiguration userConfiguration;

      public UserController(UserService userService,UserConfiguration userConfiguration) {
          this.userService = userService;
          this.userConfiguration = userConfiguration;
      }

      public void doUserController() {
        System.out.println("Do UserController!");
        userService.doService();
        userConfiguration.doConfiguration();
    }
}

import com.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test3 {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.doUserController();
    }
}

在这里插入图片描述

3.答:当有多个构造方法的时候,加了@Autowired 的构造方法才会执行,并且构造方法中的参数(对象)必须要存在于Spring容器中,否则就会报错.

典型错误 :

在这里插入图片描述
构造方法注入的优点 :

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
Spring4.2之前推荐使用Setter注入方式 , 原因是其符合单一性原则 ; Spring4.2之后则推荐使用构造方法注入 . 有意思的是Spring官方在源代码中更多使用的 , 却是属性注入的方式 , 因为这种方法确实非常简单 .

3.2 @Resource

在进行类注入时,除了可以使用 @Autowired 关键字之外,我们还可以使用 @Resource 进行注入 , 示例如下 :

在这里插入图片描述

@Resource注解不能使用在构造方法实现上 .

@Resource和@Autowired的区别

在这里插入图片描述

在这里插入图片描述

先看@Resource :

package com.controller;
import com.model.User;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

@Controller
public class SheepController {
    @Resource(name = "user1")
    private User user;

    public void doSheepController() {
        System.out.println("别看我只是一只羊");
        System.out.println(user);
    }
}

import com.controller.SheepController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test3 {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        SheepController sheepController =
                (SheepController) context.getBean("sheepController");
        sheepController.doSheepController();
    }
}

在这里插入图片描述

解释 :
在这里插入图片描述

如果使用@Autowired , 需要配合另一个Spring的注解@qualifier .

在这里插入图片描述

还可以配合@Primary注解 :

在这里插入图片描述

总结:

相同点 :
1.@Resource和@Autowired都可以作为注入属性的修饰,在接口仅有单一实现类时,两个注解的修饰效果相同,可以互相替换,不影响使用。其中属性注入和Setter , 二者使用方法及效果相同 ; @Resource不能使用在构造方法实现上 .
2. @Resource有两个属性name和type。Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型.

不同点 :
如果涉及到name和type都不能辨别注入对象时 , 可以直接为@Resource添加name属性,而@Autowired则需要依赖@Qualifier或配合Primary注解一起来修饰 .

以下是一道综合练习题 , 大家可以到我的码云查看答案 :

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

本节内容结束 !

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值