Spring五大类注解读取存储Bean对象的方法

目录
  • 前情提要
  • 配置spring-config文件
  • 类注解和方法注解
    • @Controller(控制器存储)
    • @Service(服务存储)
    • @Configuration(配置存储)
    • @Repository(仓库存储)
    • @Component(组件存储)
  • 5大类注解联系
  • Spring给Bean命名规则
  • 方法注解@Bean
    • 重命名Bean
  • 获取Bean对象(对象装配)
    • 属性注入
    • 构造方法注入
    • Setter注入
    • 三种注入方式对比
  • 注入同一类型多个Bean对象

前情提要

我们上节内容学习了如何创建\注册\读取bean
我们发现bean对象操作十分的繁琐!
所以我们这个章节,就带大家来了解更加简单的bean操作,通过Spring下的注解来实现!

配置spring-config文件

我们之前注册bean是通过在xml配置文件中,通过键值对的方式注册bean对象!
显然这种方式很麻烦,注册一个对象,就要添加一项!
有没有什么好的方式可以让spring直接去注册对象!
yes!

我们可以直接在配置文件配置好 spring下你要注册对象的包时那个!
spring启动后,spring就会将bean对象自动注册!

spring-config配置文件

<?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">
       <!--在com包下扫描bean注册-->
        <content:component-scan base-package="com"></content:component-scan>
</beans>

当然只有一个配置文件显然不够嘛!
我们如何知道我们代码中的对象是bean对象捏?
这就要引入spring五大注解概念了!
我们通过在我们创建好的对象上面添加注解的方式,就是告诉spring这个对象需要注册到容器中!

类注解和方法注解

类注解:

@Controller@Service@Repository@Component@Configuration

方法注解:
@Bean

我们可以通过上述两种注解将对象存储到Spring中!

@Controller(控制器存储)

使用@Controller注解存储bean

package com;
import org.springframework.stereotype.Controller;
@Controller //通过Controller注解存储bean对象
public class UserController {
    public void sayHi(){
        System.out.println("hello Controller注解!");;
    }
}

我们通过在UserController类上加上spring类注解,即可完成注册对象!

在启动类中读取bean对象即可!

//启动类
public class app{
    public static void main(String[] args) {
        //1.获取上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //读取bean对象!
        UserController userController =
                (UserController) context.getBean("userController");
        //使用
        userController.sayHi();
    }
}

如果我们的需要注册的bean对象不在扫描包下,是否又能注册成功呢?

我们在新建一个controller包在其下创建TestController类,并且通过@Controller注册到Spring中!

package controller;
import org.springframework.stereotype.Controller;
@Controller //注册到Spring中!
public class TestController {
    public void sayHi(){
        System.out.println("该bean不在扫描的包下");
    }
}

然后我们通过ApplicationContext上下文对象读取bean

可以看到出现异常未找到名为textControllerbean对象!

结论:只有在扫描包下的类才能被Spring注册

@Service(服务存储)

注册bean

package com;

import org.springframework.stereotype.Service;

@Service // @Service 注解注册对象!
public class UserService {
    public  void sayHi(){
        System.out.println("Hello Service注解!");
    }
}

读取bean

@Configuration(配置存储)

package com;
import org.springframework.context.annotation.Configuration;
@Configuration //Configuration注解注册bean对象
public class UserConfiguration {
    public void sayHi(){
        System.out.println("Hello Configuration注解!");
    }
}

@Repository(仓库存储)

package com;

import org.springframework.stereotype.Repository;

@Repository //@Respository 注解注册对象
public class UserRepository {
    public void sayHi(){
        System.out.println("Hello Respository注解!");
    }
}

@Component(组件存储)

package com;

import org.springframework.stereotype.Component;

@Component //Component注解注册对象!
public class UserComponent {
    public void sayHi(){
        System.out.println("Hello Component注解!");
    }
}

5大类注解联系

可以看到这5大类注解使用方式一样,都可以对对象进行注册!
而且注册的方式都一样,既然如此为何还需要5个注解呢?

我们联系实际生活中的车牌号,我们虽然车牌号的功能都是一样,但是不同地区都有自己的车牌号!我们通过车牌号就可以分辨出这车来自哪里!
而这里5大类注解作用也是如此,我们通过类注解,可以知道当前类的用途!
例如;

@Controller:表示业务逻辑层
@Service:服务层
@Repository:持久层
@Configuration:配置层

程序的工程分层,调用流程如下:

我们拿去银行办业务做类比:

@Controller层就是保安,先要进行检查验证,然后到达Service服务厅询问业务,不同的业务来到Repository,不同的窗口,然后进行相应的工作人员办理业务!

类注解之前联系:

可以看到其他4个注解都是Component注解的子类!

Spring给Bean命名规则

我们可以看到我们刚刚读取bean对象时,我们并不知道bean对象注册的id而是直接通过userController读取!
难道说Spring注册bean对象id为类名首字母小写,直接就小驼峰?

我们查看Spring源码验证!

我们顺藤摸瓜下方就是Spring对Bean对象进行命名的方法!

 public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

可以看到我们这里bean对象的id命名规则如下:

对象类类名一般采用大驼峰的形式也就是单词第一个字母大小,所以Spring直接bean对象改为小驼峰,`第一个字母分成小写!对象类类名不规范,不是大驼峰,第二个字母和第一个字母都是大小!Spring直接将bean对象命名为类名!

我们进行验证:

方法注解@Bean

我们了解了5大类注解可以进行对象注册,我们使用方法注解进行对象注册!
注意: 方法注解要和类注解配合使用!

方法注解进行对象注册

//User类
public class User {
    private String name;
    private int id;
    public User(String name, int id) {
        this.name = name;
        this.id = id;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}
//Users类
@Component
public class Users {
    @Bean
    public User user(){
        return new User("java",666);
    }
}

可以看到@Bean注解适用于返回值返回对象的方法中!

重命名Bean

我们既然可以通过五大类注解进行对象注入!那为何还要多此一举在方法上加上@Bean方法注解呢?

我们可以通过@Bean方法注解给bean对象重命名,可以直接设置名字!

通过 name={"rename1", "rename2"...}可以重命名多个!

@Component
public class Users {
    @Bean(name = {"user1"})
    public User user(){
        return new User("java",666);
    }
}

能否通过之前Spring给我们设置的名字访问? 不能

@Bean(name={"user1","user2"}) 重命名多个!

我们也可以将name省略
@Bean({"user1"})

获取Bean对象(对象装配)

这里可能听了有点迷,啥玩意对象装配,其实就是获取对象!
我们将对象注册到Spring容器下,我们要读取将对象取出放入到某个类中,这就是对象装配,也叫对象注入!

实现对象装配的3种方法

  • 属性注入
  • 构造方法注入
  • Setter注入

下面我们来演示一下这3种注入方式

我们按照实际开发将Service层的类注入到Controller层的类中!

属性注入

我们通过@Autowired实现属性注入
service层类代码

@Service
public class UserService {
    public User getUser(){
        return new User("Mysql",666);
    }
}

controller层类代码
通过属性注入将service层代码注入到这

@Controller
public class UserController {
    //属性注入
    @Autowired
    private UserService userService;
    public User getUser(){
        return userService.getUser();
    }
}

运行结果:

构造方法注入

我们还是通过@Autowired注解注入

@Controller
public class UserController {

    private UserService userService;
    //构造方法注入
    @Autowired
    public UserController(UserService userService){
        this.userService = userService;
    }
    public User getUser(){
        return userService.getUser();
    }
}

Setter注入

@Controller
public class UserController {
    //Setter注入
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService;
    }
    public User getUser(){
        return userService.getUser();
    }
}

三种注入方式对比

  • 属性注入简洁,使用方便! 缺点只能适用于IoC容器,在非IoC容器不适用,并且属性注入只有在是使用的时候才会出现空指针异常(NPE)
  • 构造方法注入现在官方推荐注入方式! 缺点 如果注入多个对象,就会使得代码臃肿,不过这就是程序员的问题了,不符合程序设计的单一职责的设计模式,优点通用性强,在使用前一定可以保证注入的类不为空!
  • Setter方式是Spring前期推荐的注入方式,通用性不如构造方法注入,现在已经认准构造方法注入!

在进行类注入时,我们还可以通过@Resource注解进行注入!
我们只需要将@Autowired注解换成@Resource即可!

@Autowired@Resource区别

  • 出身不同: @Autowired注解是Spring提供的,@Resource是来自JDK下的注解
  • 使用设置的参数不同:相比@Autowired注解,@Resource注解 支持更多的参数设置 例如name设置,根据name获取对象

注入同一类型多个Bean对象

我们在Users类中注册了2个相同类型的Bean对象!

@Component
public class Users {
    @Bean(name = "user1")
    public User user1(){
        User user =  new User("java",666);
        return user;
    }
    @Bean(name = "user2")
    public User user2(){
        User user = new User("MySQL",666);
        return user;
    }
}

当我们直接注入到Controller类中!

@Controller
public class UserController {
    @Resource
    private User user;
    public User getUser(){
        return user;
    }
}

因为我们在Spring中注册了2个相同类型的User对象,所以进行对象装配时,也需要通过name属性进行声明你要装配的对象名!

@Controller
public class UserController {
    @Resource(name = "user2")
    private User user;
    public User getUser(){
        return user;
    }
}

注意:

@Resource注解才提供了name属性,如果用@Autowried需要加上@Qualifier 注解定义名称

@Controller
public class UserController {
//    @Resource(name = "user2")
    @Autowired
    @Qualifier(value = "user1")
    private User user;
    public User getUser(){
        return user;
    }
}

到此这篇关于Spring五大类注解读取存储Bean对象的文章就介绍到这了,更多相关Spring 读取存储Bean对象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot2.x解决运行顺序及Bean对象注入顺序的问题

    1 前言 通过指定接口,重写指定方法,可以在Bean对应的生命周期方法中执行相应的程序 2 测试 本文将分析几个Bean对象,为它们设置优先级(通过@Order),然后再打断点调试,测试各种生命周期方法的运行的顺序 在项目当中最让人头疼的就是bean对象不被注入的问题,通过本文,你可以很好的解决这个问题. 先看看本程序使用的依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="

  • Java 如何从spring容器中获取注入的bean对象

    1.使用场景 控制层调用业务层时,控制层需要拿到业务层在spring容器中注入的对象 2.代码实现 import org.apache.struts2.ServletActionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.suppo

  • Spring bean对象实例化实现过程图解

    好了 我们聊聊 Bean 的实例化过程的几个重要角色 BeanDefinitionRegistryPostProcessor 接口 Refresh().invokeBeanFactoryPostProcessors 这个方法里面. BeanDefinitionRegistryPostProcessor 这个接口的调用分为三部: 1.调用实现了 PriorityOrdered 排序接口 2.调用实现了 Ordered 排序接口 3.没有实现接口的调用 这个接口我的理解:获取 BeanDefinit

  • spring实现bean对象创建代码详解

    我以一个简单的示例解构spring是怎样管理java对象的. 首先,定义一个简单的pojo,代码如下: package com.jvk.ken.spring; public class Demo { private String name; public Demo() { name="I'm Demo."; } public void printName() { System.out.println(name); } public void setName(String name) {

  • SpringBoot如何使用ApplicationContext获取bean对象

    目录 使用ApplicationContext获取bean对象 SpringBoot Bean注入的深入研究 下面代码可正常运行 下面代码不能正常运行 比较 解决方案 应用 使用ApplicationContext获取bean对象 编写一个ApplicationContextFactory工厂类 public class ApplicationContextFactory{ private static ApplicationContext applicationContext = null;

  • Spring五大类注解读取存储Bean对象的方法

    目录 前情提要 配置spring-config文件 类注解和方法注解 @Controller(控制器存储) @Service(服务存储) @Configuration(配置存储) @Repository(仓库存储) @Component(组件存储) 5大类注解联系 Spring给Bean命名规则 方法注解@Bean 重命名Bean 获取Bean对象(对象装配) 属性注入 构造方法注入 Setter注入 三种注入方式对比 注入同一类型多个Bean对象 前情提要 我们上节内容学习了如何创建\注册\读

  • spring中通过ApplicationContext getBean获取注入对象的方法实例

    用SpringContextUtil实现ApplicationContextAware package util; import java.util.Locale; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; pub

  • Spring Security将用户数据存储到数据库的方法

    一.UserDetailService Spring Security 支持多种不同的数据源,这些不同的数据源最终都将被封装成 UserDetailsService 的实例,在微人事(https://github.com/lenve/vhr)项目中,我们是自己来创建一个类实现 UserDetailsService 接口,除了自己封装,我们也可以使用系统默认提供的 UserDetailsService 实例,例如上篇文章和大家介绍的 InMemoryUserDetailsManager . 我们来

  • spring mvc利用ajax向controller传递对象的方法示例

    前言 最近因为工作的需要,在写一个基于springmvc+spring+mybatis的项目,其中涉及用ajax向controller发送数据的功能.因为不想使用spring的form标签,所以想看看有没有方法将ajax中的json数据直接转化为controller方法中的对象接收并处理.以下将逐渐介绍各种不同情况下传递json数据并封装的方法,下面话不多说,一起来看看详细的介绍: 基础类型 如果传递的json数据为基础类型(Int,String等)的话,则只需要用@RequestParam标注

  • Spring如何通过注解存储和读取对象详解

    目录 1. 创建Spring 项目 1.1 创建⼀个 Maven 项⽬ 1.2 添加 Spring 框架支持 1.3 添加启动类 2. 存储 Bean 对象 2.1 创建Bean 2.2 配置 spring-config.xml 3. 获取并使用 Bean 对象 3.1 创建Sprign 上下文 3.2  获取指定的 Bean 对象 3.3 使用Bean 4.总结 5.配置扫描路径 6.添加注解存储 6.1 @Controller(控制器存储) 6.2 @Service (服务器存储) 6.3

  • SpringBoot 普通类调用Bean对象的一种方式推荐

    目录 SpringBoot 普通类调用Bean对象 SpringBoot 中bean的使用 SpringBoot 普通类调用Bean对象 有时我们有一些特殊的需要,可能要在一个不被Spring管理的普通类中去调用Spring管理的bean对象的一些方法,比如一般SpringMVC工程在controller中通过 @Autowired private TestService testService; 注入TestService 接口就可以调用此接口实现类的实现的方法. 但在一般类中显然不可以这么做

  • Spring通过配置文件管理Bean对象

    目录 一.Bean对象 二.存储Bean对象 1. 添加配置xml文件 2. 创建上下文 三.获取Bean对象 提示:以下是本篇文章正文内容,Java系列学习将会持续更新 一.Bean对象 Bean是Spring框架在运行时管理的对象, 是需要放置在Spring容器中进行管理的. Spring容器: BeanFactory接口(bean工厂)——> ApplicationContext接口(应用上下文)实现Spring容器的方法:基于xml文件.基于注解,我们接下来演示通过修改xml配置文件的方

  • spring在IoC容器中装配Bean详解

    1.Spring配置概述 1.1.概述 Spring容器从xml配置.java注解.spring注解中读取bean配置信息,形成bean定义注册表: 根据bean定义注册表实例化bean: 将bean实例放入bean缓存池: 应用程序使用bean. 1.2.基于xml的配置 (1)xml文件概述 xmlns------默认命名空间 xmlns:xsi-------标准命名空间,用于指定自定义命名空间的schema文件 xmlns:xxx="aaaaa"-------自定义命名空间,xx

  • 详解Spring Boot 使用Java代码创建Bean并注册到Spring中

    从 Spring3.0 开始,增加了一种新的途经来配置Bean Definition,这就是通过 Java Code 配置 Bean Definition. 与Xml和Annotation两种配置方式不同点在于: 前两种Xml和Annotation的配置方式为预定义方式,即开发人员通过 XML 文件或者 Annotation 预定义配置 bean 的各种属性后,启动 spring 容器,Spring 容器会首先解析这些配置属性,生成对应都?Bean Definition,装入到 DefaultL

随机推荐