Spring更简单的读取和存储对象

目录

常用注解

前置工作

五大类注解

使用Controller注解

五大类注解bean对象的命名规则

使用其他类注解

注意事项

五大类注解的关系

为什么需要五大注解

方法注解

注意事项

@Bean重命名

更简单的获取Bean对象(对象装配)

属性注入(Field Injectoon)

Setter注入(Setter Injection)

构造方法注入(Constructor Injection)

另一种注入关键字:@Resource

@Autowired和@Resource的区别

同一类型多个@Bean报错


前一章我们学习了Spring如何读取和存储对象,我们是在配置文件中,通过添加bean标签的方式,来将我们的bean注册到Spring容器当中.当我们的项目中bean对象很多的时候,这个方法就很麻烦了,所以接下来我们要学习更加简单的读取和存储bean对象.

在Spring中更简单的存储和读取对象的核心就是使用注解,包括类注解和方法注解.因此我们先来了解一下,Spring当中更简单的存Bean对象的注解.

常用注解

五大类注解

  • @Controller:控制器,用来验证用户请求的数据的正确性.
  • @Service:服务,用来编排和调度具体的执行方法.
  • @Repository:持久层,和数据库进行交互.
  • @Component:组件,工具类.
  • @Configuration:配置项,项目中的一些配置.

方法注解 @Bean


前置工作

我们在使用注解之前,必须要完成一个前置工作:配置扫描路径.

只有被配置的包下的所有类,添加了注解才能被正确识别并保存到Spring中.

只有在这个包下的类,才会去扫描,是否添加了五大类注解.

<?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="com.java.demo"></content:component-scan>
</beans>

五大类注解

使用Controller注解

在demo的包下创建一个StudentController类,并使用@Controller注解.

 在我们的启动类中去获取并调用,看是否能正确打印.

 打印结果:

 由此我们可以看到,加了@Controller类注解,不需要在去配置文件中添加baen标签,在加载Spring配置文件的时候,Spring会自动的帮我们将带有类注解的对象存储到Spring容器当中去.

这里我们要注意一个问题,bean对象的id是怎么确定的?

五大类注解bean对象的命名规则

如果原类名的第一个字符和第二个字符是大写的,那么bean名称就是原类名;如果不满足上述条件,bean名称就是使用原类名并且首字母小写.


使用其他类注解

只要会用了@Controller,其他的就很简单.我们来依次演示一下:

 

 打印结果:


注意事项

演示完了用法就有几个问题需要明确一下.

<bean>标签能否和component-scan一起使用??

我们在com.java.service包下创建一个UserService类,将它使用bean标签的方式注册到Spring容器中,在启动类中看看是否可以获取到它.

 

由此我们可以看到,这两个是可以一起使用的.


五大类注解可以不在component-scan的包下吗?

答案:不可以,只有在component-scan包下的才会去扫描是否添加了五大类注解.

注意:即使在conponent-scan下,但是如果没有加五大类注解,一样是不能将当前对象存储到Spring.

在component-scan的所有子包下的类,只要加了五大类注解,同样能存储到Spring中.


五大类注解的关系

可以认为@Controller/@Service/@Repository/@Configuration 都是@Component 的"子类",都是针对@Component的一个扩展.


为什么需要五大注解

让程序员看到注解之后就知道当前类的作用.

JavaEE标准分层:

 至少3层:控制层,服务层,数据持久层.

这么多注解其实就是为了满足标准分层的需求.


方法注解

使用方法注解@Bean 存储对象到Spring容器.

首先我们先创建一个实体类User:

package com.java.demo.entity;

/**
 * 普通用户的实体类
 */
public class User {
    private Integer uid;
    private String username;
    private String password;
    private Integer age;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 然后在创建一个UserBeans类,在这个类里使用@Bean方法注解

用Bean对象来接受当前这个方法的返回值.

最后在启动类里获取bean对象:

 

由此可以看到我们通过方法注解的方式将当前方法的返回值存到容器中,再从容器里获取是可行的.


注意事项

使用@Bean方法注解需要注意两个点:

1.@Bean的命名规则和五大类注解的命名规则不同.@Bean的命名规则,默认情况下@Bean存储的对象名称是方法名.

2.@Bean注解必须要配合五大类注解一起使用.这是基于Spring的性能所设计的一种策略.


@Bean重命名

 

底层是一个数组,可以起多个名字.

但是需要注意的是:当@Bean使用了重命名之后,默认的方法名获取对象的方式已经不能使用了,重命名了就只能用重命名的名字.


更简单的获取Bean对象(对象装配)

获取Bean对象也叫做对象装配,是把对象取出来放到某个类中,也叫做对象注入.

直白一点讲就是A类中需要B类,把B类从Spring中装配到A类当中,这叫做对象装配,也叫做对象注入,也是DI,名字有很多,但是实现的功能都是一致的.(更加简单的读取Bean,是从Spring容器中读取某个对象,放到当前类里面)

对象装配的实现方法有三种:属性注入,Setter注入,构造方法注入.

注入依赖的注解是:@Autowired

属性注入(Field Injectoon)

属性注入是最简单的,也是日常开发中使用最多的一种注入方式.

实现代码:

目标:从UserController里面通过简单的方式获取到UserService.

验证:在启动类里获取到UserController,调用它的sayHi方法.

 

 

从打印结果可以看到,我们从UserController里面是获取到了UserService对象的. 

优点:简单

缺点:1.没办法实现final修饰的变量注入.

2.兼容不好,只适用于IoC容器.

3.风险:因为写法简单,所以违背单一设计原则的概率更大.

Setter注入(Setter Injection)

实现代码

 

优点:符合单一设计原则(每个方法只传递一个对象)

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

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

构造方法注入(Constructor Injection)

优点:

1.可以注入一个不可变的对象(使用final修饰的对象)

为什么构造方法可以注入一个不可变的对象,而属性注入和setter注入却不行?

这是Java的规定,在Java中被final修饰的对象必须满足以下两个条件中的任意一个:

  • a.final 修饰i的对象,直接赋值.
  • b.final修饰的对象,必须在构造方法中赋值.

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

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

4.通用性更好


另一种注入关键字:@Resource

在进行对象注入的时候,除了可以使用@Autowired关键字外,还可以使用@Resource.


@Autowired和@Resource的区别

  1. 出身不同:@Autowired来自于Spring,@Resource来自于JDK的注解.
  2. 使用时设置的参数不同:相对于@Autowired来说,@Resource支持更多的参数设置.
  3. @Autowired可以用于属性注入,Setter注入,构造方法注入,而@Resource只能用于属性注入和Setter注入,不能用于构造方法注入.
  4. 在Spring容器中找Bean有两种方式,1是根据类型查找2是根据名称查找.@Autowired先根据类型查找,之后在根据名称查找;@Resource先根据名称查找,在根据类型查找.

同一类型多个@Bean报错

User类型的对象在Spring容器中存了多个:

package com.java.demo.component;
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

@Component
public class UserBeans {

    @Bean(name = {"u1","user1"})
    public User getUserById(){
        User user = new User();
        user.setUid(1);
        user.setUsername("张三");
        user.setPassword("123456");
        user.setAge(18);
        return user;
    }

    @Bean
    public User getUserByName(){
        User user = new User();
        user.setUid(2);
        user.setUsername("李四");
        user.setPassword("1234");
        user.setAge(20);
        return user;
    }
}

在UserController2中获取User对象:

package com.java.demo.controller;
import com.java.demo.entity.User;
import com.java.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {

    @Autowired //默认是把属性名字当作Bean对象名称去容器里查找
    private User user;
    public void sayHi(){
        System.out.println("do UserController sayHi()");
        System.out.println(user.getUsername());
    }
}

在启动类中测试:

 发现报错了:

 

 报错的大体意思是:没有找到唯一的Bean异常,找到了两个u1,和getUserByName.

因为我们是使用了@Autowired,先根据类型查找,发现有两个,在根据名称去查找,还是不能确定,所以就报错了.同理使用@Resource也会报错.

解决上述问题:

解决方案有两个,使用@Resource设置name属性或使用@Autowired搭配@Qualifier(筛选).

 


 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security 是一个用于身份验证和授权的框架,它的源码读取顺序可以大致分为以下几个步骤: 1. 加载配置文件:Spring Security 使用 XML 或 Java Config 的方式进行配置,首先会加载配置文件,获取安全配置的相关信息。 2. 创建过滤器链:Spring Security 通过过滤器链来处理请求,根据配置文件中的顺序,创建不同的过滤器,并将它们按照一定的顺序组成过滤器链。 3. 加载认证信息:在过滤器链中,有一个特殊的过滤器称为 `UsernamePasswordAuthenticationFilter`,它负责处理用户名密码的认证。在请求到达该过滤器时,会根据配置的认证方式加载用户信息,例如从数据库或者内存中加载用户信息。 4. 执行认证逻辑:在认证过滤器中,会调用相应的 `AuthenticationManager` 进行认证。`AuthenticationManager` 是一个接口,具体的实现类是 `ProviderManager`,它会根据配置中的认证提供者(`AuthenticationProvider`)来进行认证操作。 5. 认证结果处理:认证完成后,会根据认证结果进行相应的处理。例如,如果认证成功,会生成一个身份验证凭证(`Authentication`)对象,并将其保存到 `SecurityContextHolder` 中,供后续的授权操作使用。 6. 执行授权逻辑:在过滤器链中,有一个称为 `FilterSecurityInterceptor` 的过滤器,它负责处理授权逻辑。当请求到达该过滤器时,会根据配置的访问规则进行权限检查,并决定是否允许请求进入。 7. 异常处理:在整个过程中,如果发生异常,Spring Security 会根据配置的异常处理机制进行相应的处理,例如重定向到登录页面或返回错误信息。 这只是 Spring Security 源码的一个简要读取顺序,具体的实现细节和流程会加复杂,涉及到很多不同的类和接口。如果你想深入了解 Spring Security 的源码,建议阅读官方文档以及相关的源码注释和示例代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值