Spring——读取和存储(包含五大注解,对象装配,注入关键字)

目录

一、创建Spring项目

1. 创建一个普通的maven项目

2. 添加Spring框架支持(spring-context,spring-beans)

3. 添加启动类

二、Bean对象的读取和存储——不使用注释版

1. 创建Bean

2. 将Bean注册到容器

3. 获取并使用Bean对象

3.1 创建Spring上下文

3.2 获取指定的Bean对象

getBean方法的用法

3.3 使用Bean

4. 总结步骤

三、Bean对象的读取和存储——使用注解版

1. 存储Bean对象

1.1 配置扫描路径

1.2 添加注解存储Bean对象

2. 获取Bean对象(对象装配)

2.1 属性注入

2.2 构造方法注入

2.3 Setter注入

2.4 三种注入优缺点分析

2.5 @Resource:另一种注入关键字

2.5 同⼀类型多个 Bean 报错处理

3. 总结


一、创建Spring项目

1. 创建一个普通的maven项目

2. 添加Spring框架支持(spring-context,spring-beans)

在项目的pom.xml中添加Spring框架的支持:

 <dependencies>
 <dependency>
<groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>5.2.3.RELEASE</version>
 </dependency>
 
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>5.2.3.RELEASE</version>
 </dependency>
</dependencies>

3. 添加启动类

在java文件夹下创建一个启动类,包含main方法

public class App {
    public static void main(String[] args) {
      
    }
}

二、Bean对象的读取和存储——不使用注释版

1. 创建Bean

Bean就是一个普通的对象。

public class User {
    public String sayHi(String name){
        return name + "hello!";
    }
}

2. 将Bean注册到容器

添加Spring配置文件spring-config.xml(名字不能改),将文件放到resoources的根目录下。

我这里目录如下:

spring-config.xml(固定格式,无需记忆,保存到能找到的地方):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

将User对象注册到Spring中,在<beans>中添加如下配置:

<beans>
<bean id = "user" class="Bean.User"></bean>
</beans>

修改后的spring-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id = "user" class="Bean.User"></bean>
</beans>

3. 获取并使用Bean对象

有以下3步:

  • 创建Spring上下文。
  • 获取指定的Bean对象。
  • 使用Bean。

3.1 创建Spring上下文

有两种方式:

  • 使用ApplicationContext
  • 使用BeanFactory

(1). 使用ApplicationContext

// 1.得到 Spring 的上下⽂对象,创建的时候需要配置 Spring 配置信息
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

(2). 使用BeanFactory

BeanFactory beanFactory = new XmlBeanFactory(newClassPathResource("springconfig.xml"));

(3).  ApplicationContext和BeanFactory

        ApplicationContext和BeanFactory的效果是一样的,ApplicationContext属于BeanFactory的子类。

  • 继承关系和功能方面:Spring容器有两个顶级接口: ApplicationContext和BeanFactory。其中BeanFactory提供了基础的访问容器的能力,而ApplicationContext属于BeanFactory的子类,除了继承BeanFactory的所有功能之外,它还拥有独特的特性,添加了对国际化支持,资源访问支持,以及事件传播等方面的支持。
  • 性能方面:ApplicationContext是一次性加载并初始化所有Bean对象,而BeanFactory是需要哪个才去加载哪个,因此更加轻量。

PS:ClassPathXmlApplicationContext 属于 ApplicationContext 的⼦类,拥有ApplicationContext 的所有功能,是通过 xml 的配置来获取所有的 Bean 容器的。

3.2 获取指定的Bean对象

// 1.得到 Spring 上下⽂对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.加载某个 bean
User user = (User) context.getBean("user");

注意:Bean的Id要一一对应。

getBean方法的用法

(1). 根据类型获取Bean

UserController user = context.getBean(UserController.class);

(2). 名称+类型获取Bean

UserController user = context.getBean("user", UserController.class);

(3). 区别

 当一个类型被重复注册到spring-config.xml中时,只能使用根据名称获取。

3.3 使用Bean

public class App {
    public static void main(String[] args) {
        // 1.得到 Spring 的上下⽂对象,创建的时候需要配置 Spring 配置信息
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.加载某个bean
        User user = (User) context.getBean("user");
        // 3.调用相应方法
        System.out.println(user.sayHi("Java"));
    }
}

4. 总结步骤

1. 先得到容器。

2. 存对象

  • 创建Bean(普通类)。
  • 将Bean注册(配置)到spring-confing.xml中。

3. 取对象

  • 得到 Spring 上下⽂,并读取到 Spring 的配置⽂件。
  • 获取某⼀个 Bean 对象。
  • 使⽤ Bean 对象。

三、Bean对象的读取和存储——使用注解版

1. 存储Bean对象

1.1 配置扫描路径

添加Spring配置文件spring-config.xml(名字不能改),将文件放到resoources的根目录下。

spring-config.xml:

<?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="org.example"></content:component-scan>
</beans>

其中圈中的这一行为注册扫描的包,需要自己修改,我这里目录如图:

 

所以也就是说,即使添加了注解,如果不是在配置的扫描包下的类对象,也是不能被存储到Spring中的。

1.2 添加注解存储Bean对象

想要将对象存储在 Spring 中,有两种注解类型可以实现:

  • 类注解:@Controller、@Service、@Repository、@Component、@Configuration。
  • ⽅法注解:@Bean。

1.2.1 类注解 

(1). @Controller——控制器存储,表示业务逻辑层

@Controller
public class UserController {
    public void sayHi(String name){
        System.out.println("HiController" + name);
    }
}
public class Main {
    public static void main(String[] args) {
        //1. Controller
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserController userController = (UserController) context.getBean("userController");
        // 3.调⽤ bean ⽅法
        userController.sayHi("Controller");
    }
}

(2). @Service——服务存储

@Service
public class UserService {
    public void sayHi(String name){
        System.out.println("HiService" + name);
    }
}
public class Main {
    public static void main(String[] args) {
        //2. Service
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserService userService = (UserService) context.getBean("userService");
        // 3.调⽤ bean ⽅法
        userService.sayHi("Service");

    }
}

(3). @Repository——仓库存储(数据库)

@Repository
public class UserRepository {
    public void sayHi(String name){
        System.out.println("HiRepository" + name);
    }
}
public class Main {
    public static void main(String[] args) {
        //3. Repository
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        // 3.调⽤ bean ⽅法
        userRepository.sayHi("Repository");
    }
}

(4). @Component——组件存储

@Component
public class UserComponent {
    public void sayHi(String name){
        System.out.println("HiComponent" + name);
    }
}
public class Main {
    public static void main(String[] args) {
        //4. Component
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserComponent userComponent = (UserComponent) context.getBean("userComponent");
        // 3.调⽤ bean ⽅法
        userComponent.sayHi("Component");
    }
}

(5). @Configuration——配置存储

@Configuration
public class UserConfiguration {
    public void sayHi(String name){
        System.out.println("HiConfiguration" + name);
    }
}
public class Main {
    public static void main(String[] args) {
        //5. Configuration
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserConfiguration userConfiguration = (UserConfiguration) context.getBean("userConfiguration");
        // 3.调⽤ bean ⽅法
        userConfiguration.sayHi("Configuration");
    }
}

注意:

  • 为什么需要这么多类注解?因为这样可以更方便让程序员看到注解后直接了解当前类的用途。 
  • 类注解之间的关系:@Controller、@Service、@Repository、@Configuration都是@Component的“子类”。

Bean的命名规则:

1. 类名前两个字母只有首字母大写,读取时将首字母改为小写。


 2. 类名前两个字母都是大写,读取时保持不变。

1.2.2 方法注解@Bean

类注解是添加到某个类上的,方法注解是放到某个方法上的。

 ⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中。

1.2.2.1 使用

@Component
public class Users {
    @Bean
    public User user1() {
        User user = new User();
        user.sayHi("Java");
        return user;
    }
}
public class Main2 {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        User user = (User) context.getBean("user1");
        // 3.调⽤ bean ⽅法
        user.sayHi("hhh");
    }
}

 

1.2.2.2 重命名Bean

@Component
public class Users {
    @Bean(name ={"u1"})
    public User user1() {
        User user = new User();
        user.sayHi("Java");
        return user;
    }
}
public class Main2 {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        User user = (User) context.getBean("u1");
        // 3.调⽤ bean ⽅法
        user.sayHi("hhh");
    }
}

这个重命名的 name 其实是⼀个数组,⼀个 bean 可以有多个名字:

@Component
public class Users {
    @Bean(name = {"u1","us1"})
    public User user1() {
        User user = new User();
        user.sayHi("Java");
        return user;
    }
}

并且 name= 可以省略,如下所示:

@Component
public class Users {
    @Bean({"u1","us1"})
    public User user1() {
        User user = new User();
        user.sayHi("Java");
        return user;
    }
}

2. 获取Bean对象(对象装配)

        获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊

 对象装配(对象注⼊)的实现⽅法以下 3 种:

  • 属性注⼊
  • 构造⽅法注⼊
  • Setter 注⼊

以将Service 类注⼊到 Controller 类中举例:

2.1 属性注入

        属性注⼊是使⽤ @Autowired 实现的。

 Service类:

@Service
public class UserService {
    public void sayHi(String name){
        System.out.println("HiService" + name);
    }
}

Controller类:

@Controller
public class UserController {
    public void sayHi(String name){
        System.out.println("HiController" + name);
        userService.sayHi(name);
    }

    //属性注入
    @Autowired
    private UserService userService;
}
public class Main3 {
    public static void main(String[] args) {      
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserController userController = (UserController) context.getBean("userController");
        // 3.调⽤ bean ⽅法
        userController.sayHi("Controller");
    }
}

 输出:

2.2 构造方法注入

@Controller
public class UserController2 {
    //构造方法注入
    private UserService userService;

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

    public void sayHi(String name){
        System.out.println("HiController" + name);
        userService.sayHi(name);
    }
}
public class Main4 {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserController2 userController2 = (UserController2) context.getBean("userController2");
        // 3.调⽤ bean ⽅法
        userController2.sayHi("Controller2");
    }
}

注意:

如果只有⼀个构造⽅法,那么 @Autowired 注解可以省略,但是如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法,否则程序会报错。

2.3 Setter注入

        Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注解。

@Controller
public class UserController3 {
    //Setter注入
    private UserService userService;

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

    public void sayHi(String name){
        System.out.println("HiController" + name);
        userService.sayHi(name);
    }
}
public class Main5 {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean 默认类名首字母小写
        UserController3 userController3 = (UserController3) context.getBean("userController3");
        // 3.调⽤ bean ⽅法
        userController3.sayHi("Controller3");
    }
}

2.4 三种注入优缺点分析

  • 属性注⼊的优点是简洁,使⽤⽅便;缺点是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)。
  • 构造⽅法注⼊是 Spring 推荐的注⼊⽅式,它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了,它的优点是通⽤性,在使⽤之前⼀定能把保证注⼊的类不为空。
  • Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法,所有 Spring 现版本已经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了。

2.5 @Resource:另一种注入关键字

@Controller
public class UserController4 {
    @Resource
    private UserService userService;
    
    public void sayHi(String name){
        System.out.println("HiController" + name);
        userService.sayHi(name);
    }
}

@Autowired 和 @Resource 的区别:

  • 出身不同:@Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解;
  • 使⽤时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如name 设置,根据名称获取 Bean。
  • @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注⼊和属性注⼊,不能⽤于构造函数注⼊。

2.5 同⼀类型多个 Bean 报错处理

        解决同⼀个类型,多个 bean 的解决⽅案有以下两个:

  • 使⽤ @Resource(name="user1") 定义。
  • 使⽤ @Qualifier(value = "user2")  注解定义名称。
@Component
public class Users {
    @Bean
    public User user1() {
        User user = new User();
        user.sayHi("user1");
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.sayHi("user2");
        return user;
    }
}

2.5.1 使用 @Resource(name="user1") 定义

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

    public void sayHi(String name){
        System.out.println("HiController" + name);
        user.sayHi(name);
    }
}

 2.5.2 使用 @Qualifier(value = "user2")  注解定义名称

@Controller
public class UserController5 {
    @Autowired
    @Qualifier("user2")
    private User user;

    public void sayHi(String name){
        System.out.println("HiController" + name);
        user.sayHi(name);
    }
}

3. 总结

将对象存储到 Spring 中:

  • 使⽤类注解:@Controller、@Service、@Repository、@Configuration、@Component【它们之间的关系】
  • 使⽤⽅法注解:@Bean【注意事项:必须配合类注解⼀起使⽤】

Bean 的命名规则:

        ⾸字⺟和第⼆个字⺟都⾮⼤写,⾸字⺟⼩写来获取 Bean,如果⾸字⺟和第⼆个字⺟都是⼤写,那么直接使⽤原 Bean 名来获取 Bean。

从 Spring 中获取对象:

  • 属性注⼊
  • Setter 注⼊
  • 构造函数注⼊

注⼊的关键字有:

  • @Autowired
  • @Resource

@Autowired 和 @Resource 区别:

  • 出身不同;
  • 使⽤时设置参数不同 @Resource ⽀持更多的参数,⽐如 name。

解决同⼀类型多个 Bean 的报错:

  • 使⽤ @Resource(name="")
  • 使⽤ @Qualifier("")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring注入注解是一种在Spring框架中进行依赖注入的方式。通过使用注解,我们可以方便地将依赖对象注入到需要使用它们的类中,从而实现解耦和灵活性。 Spring框架提供了多种注入注解,常用的有: 1. `@Autowired`:自动装配,通过类型进行匹配注入。可以用在构造方法、属性、方法上。当需要注入对象容器中有多个实例时,可以结合`@Qualifier`使用。 2. `@Inject`:与@Autowired类似,也是进行自动装配,通过类型进行匹配注入。不过@Inject是Java规范中定义的注解,需要导入`javax.inject`包才能使用。 3. `@Resource`:按名称进行注入。可以通过`name`属性指定要注入对象名称,也可以通过`type`属性指定要注入对象类型。 4. `@Value`:用于从配置文件中读取属性值并注入到类的字段中。可以使用`${}`表达式读取配置文件中的值。 5. `@Qualifier`:与@Autowired或@Resource配合使用,通过指定bean的名称来消除自动装配时的歧义性。 6. `@Primary`:与@Autowired或@Resource配合使用,当需要注入对象容器中有多个实例时,优先选择带有@Primary注解的实例。 除了上述常用的注入注解Spring还提供了其他一些注解,如`@Component`、`@Service`、`@Repository`等,用于标识组件、服务、仓库等不同的类,并将其纳入到Spring容器中进行管理。 通过使用这些注解,我们可以在Spring框架中方便地实现依赖注入,提高代码的可读性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值