IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Spring】使用五大类注解方法注解存对象@Autowired和@Resource取对象 -> 正文阅读

[Java知识库]【Spring】使用五大类注解方法注解存对象@Autowired和@Resource取对象

使用注解标识类存取对象

和我们上面使用Bean类注入spring-config.xml文件来说,这样还是比较麻烦的,因为需要我们手动的将对象引入.
所以我们又使用了一个更加简单的方式:使用注解来标识类
下面我们就来具体的看一下吧!

1.配置扫描路径

因为我们不是采用手动的注入的方式了,而是使用扫描的方式.
那么我们到底是扫描哪个文件里面的类呢?
我们就可以再Spring的配置文件中设置我们要扫描的路径
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=""></content:component-scan>  
</beans>

我们扫描的时候只扫描base-package里面的类 ,不再里面的类即使加入了注解也不会被扫描.
这个base-package里面的内容需要我们自己添加.就是存放bean对象的根目录

为什么要指定只加载特定目录里面的类呢?
因为不是所有的类,我么都想要把他放到Spring容器里面的.有的就是普通的类对象
所以,我们就只加载特定的要放入的类

但是只是将类放到这个包里面就可以运行吗?答案是当然不对的,还需要在类的前面加上注解,这两个缺一不可,下面我们就来介绍一下这个注解

2.存入对象

1.五大类注解

为了描述每一个类所属的功能,让人一看就知道这个类是干什么用的,我们就引入这个五大类的注解来帮助我们区分
@Configuration 配置类 一些负责配置信息的类
@Controller 控制类 主要是验证前端发过来的参数
@Service 服务类 数据的处理和接口的调用(Dao层的接口)
@Repository 仓库类 主要是对数据库的操作,也叫做Dao类
@Component 组件类 一些外部实现的工具类

要注意,每一个要加入Spring容器中的类的前面都要加上这个注解标识,这样的话才可以标识它已经加入到了容器中,要不然表示没有加入

五大类之间的关系

通过查看源码,我们发现,Component是其他四个类的父类
在这里插入图片描述

其他几个类也是这样的,都是Component的子类

beanName的问题

我们得到类的时候,需要得到类的名字,那个时候我们就是使用类的小驼峰的方式
比如说:UserController的BeanName就是userController
但是如果ClassName是APIController呢?难道要转为aPIController?
其实不是的,而是和他的ClassName一样还是APIController

我们到AnnotationBeanNameGenerator类里面看一下源码是怎么实现的

/**  
 * Utility method to take a string and convert it to normal Java variable * name capitalization.  This normally means converting the first * character from upper case to lower case, but in the (unusual) special * case when there is more than one character and both the first and * second characters are upper case, we leave it alone. * <p>  
 * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays * as "URL". * * @param  name The string to be decapitalized.  
 * @return  The decapitalized version of the string.  
 */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);  
}

也就是说当开头只有一个大写字母的话,那么就将第一个大写字母变为小写的
如果开头有两个以上的大写字母 ,那么就还是原来的大写字母不变

2.方法注解@Bean

和前面直接得到一个完整的类来说,还有一种获取到类的方式是通过方法来获取到类,也就是说这个方法的返回值直接就是一个类

要想要将这个返回的类放入Spring中要怎么做呢?(注意是方法返回的类)
采取的做法就是使用方法注解

我们又新创建出一个类GetUser,在这个方法中有一个Get方法,它的返回值就是User对象.

@Controller  
public class GetUser {  
    @Bean  
    public User get(){  
        User user=new User();  
        return user;  
    }  
}

注意事项:

  1. @Bean注解要放到方法的前面
  2. GetUser类也要加上五大注解中的一个,为了减少Spring的扫描范围,加上五大类注解的表示它里面含有Bean方法,这样Spring就会将被Bean修饰的类加入到Spring中

另外,我们获取到类的时候,使用的是方法名,而不是大驼峰或小驼峰了

User user=context.getBean("get",User.class);

Bean对象改名

我们上面获取到Bean修饰的方法的类使用的是方法的名字,但是这样是不太合理的,因为我们想要得到的是类,但是我们却传入了方法的名字.
所以,我们最好给每一个传入的对象都起一个别的名字

  1. 在Bean后面写一个括号,加上name属性,名字使用字符串
  2. 还可以有多个名字,多个字符串使用大括号括起来,字符串之间使用逗号分隔
  3. name这个属性也可以省略,可以直接写大括号或字符串
@Controller  
public class GetUser {  
    @Bean(name = "user1")  
    public User get1(){  
        User user=new User();  
        user.setId(1);  
        user.setName("lxy");  
        return user;  
    }  
    //可以有多个名字,使用大括号,中间使用,分隔开  
    @Bean(name ={"user2","cx"} )  
    public User get2(){  
        User user=new User();  
        user.setId(2);  
        user.setName("cx");  
        return user;  
    }  
    //也可以省略name直接写大括号  
    @Bean({"user3","lx"} )  
    public User get3(){  
        User user=new User();  
        user.setId(2);  
        user.setName("cx");  
        return user;  
    }  
}

使用了新的名字之后,我们就不可以再使用方法来获取类了
就只可以使用别名来获取类

3.得到Bean对象

现在我们来说三种得到Bean对象的三个简单方式:

1.属性注入

使用Autowired注入UserService属性

@Controller  
public class UserController {  
    @Autowired//使用属性注入的方法得到类  
    private UserService userService;  
    public void print(){  
        userService.print();  
    }  
}

2.构造方法注入

将Autowired注入构造方法那里,当我们构造这个方法的时候,就会将UserService注入这个参数里面
这个和属性直接注入相比是懒加载了,当然这个也是官方推荐的一种方式

  
@Controller  
public class UserController {  
  
    private UserService userService;  
  
    @Autowired  
    public UserController(UserService userService){  
        this.userService=userService;  
    }  
    public void print(){  
        userService.print();  
    }  
}

另外,如果一个类里面只有一个构造方法,那么就i不用使用Autowired进行修饰了

3.setter方法注入

使用setter方法注入,还是需要有Autowired注释

@Controller  
public class UserController {  
  
    private UserService userService;  
  
    @Autowired//使用setter方法进行注入,当调用setter方法的时候就注入userService  
    public void setUserService(UserService userService) {  
        this.userService = userService;  
    }  
    public void print(){  
        userService.print();  
    }  
}

4.三者的优缺点

属性注入:
优点:写法简单
缺点:只限于IOC容器下,通用性不好
构造方法注入:
优点:通用性高,在使用注入对象的时候,该注入对象早已经被构造过了,可以直接使用方法了
缺点:构造方法带有的参数可能会很多,影响使用
setter注入:
优点:早期Spring推荐的做法
缺点:和构造方法注入相比,setter注入的通用性低

5.@Resource

上面的Autowired是Spring框架提供的,但是Resource是Jdk提供的,
Resource和Autowired都是提供对象注入的
但是,Resource支持属性注入和setter注入,但是它不支持构造方法注入

4.@Autowired和@Resource的区别

  1. 出身不同:
    Autowired属于Spring框架
    Resource属于Jdk
  2. 使用范围不同:
    Autowired可以作用于构造方法注入,属性注入,setter注入
    Resource可以作用于属性注入,setter注入
  3. 参数个数不同
    Autowired只有一个参数:required
    Resource有多个参数:name,lookup,type,…

5.一个Bean对象被注入多次

如果一个Bean对象被注入了多次,那么获取对象的时候,我们怎么来区分到底是哪一个对象呢?

@Controller  
public class GetUser {  
    @Bean(name = "user1")  
    public User get1(){  
        User user=new User();  
        user.setId(1);  
        user.setName("lxy");  
        return user;  
    }  
    //可以有多个名字,使用大括号,中间使用,分隔开  
    @Bean(name ={"user2","cx"} )  
    public User get2(){  
        User user=new User();  
        user.setId(2);  
        user.setName("cx");  
        return user;  
    }  
    //也可以省略name直接写大括号  
    @Bean({"user3","lx"} )  
    public User get3(){  
        User user=new User();  
        user.setId(2);  
        user.setName("lx");  
        return user;  
    }  
}

上面一共有三个user对象,那么怎么确定要的是哪一个

1.直接写Bean的名字

第一个方法就是直接清楚的描述类的名字.
使用@Resource和@Autowired属性注入的方式,只不过在对象的名上面指定对象的名字

@Controller  
public class UserController {  
  
    @Resource  //也可以是@Autowired
    private User user2;  //这个的对象名写什么就注入什么对象
    public void print(){  
        System.out.println(user2);  
    }  
}

2.使用@Resource的name属性

在@Resource的name属性中设置对象的名字,写什么名字就注入什么名字的对象

  
@Controller  
public class UserController {  
  
    @Resource(name = "user1")//还可以写user2,user3  
    private User user;  
    public void print(){  
        System.out.println(user);  
    }  
}

这样的好处是我们不必更改UserController中的 user的名字,只要指定这个user所匹配的对象的名字就可以,相当于重命名了

3.使用@Autowired+@Qualifier

这种方法和@Resource异曲同工,因为Autowired没有name属性,所以我们采用Qualifier来帮助我们

@Controller  
public class UserController {  
  
    @Qualifier(value = "user2")  
    @Autowired  
    private User user;  
    public void print(){  
        System.out.println(user);  
    }  
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:22:54  更:2022-07-21 21:24:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:29:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码