Spring 通过注解来读取和存储对象
文章目录
- 1.存储Bean对象
- 1.1 前置工作: 配置扫描路径 (重要)
- 1.2 添加注解存储Bean对象
- 获取Bean对象
- 1.1三种注入方式
- 1.2 两种注入方法
- 2.1当 @Bean 将一个类型对象注入多次的问题
- 2.2 解决方案
1.存储Bean对象
之前的是需要再 spring-config.xml 下 导入bean的:
1.1 前置工作: 配置扫描路径 (重要)
<?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.beans"></content:component-scan>
</beans>
在这里指定的是com.beans目录
也就是所有要存放到spring当中的bean,都要在这个目录下, 或者子目录下.
1.2 添加注解存储Bean对象
简单将 bean 存储到容器:
a) 五大注解:
@Conroller [控制器]
@Service [服务]
@Repoistory [仓库]
@Configuration [配置]
PS: 注意这里添加的注解是Configuration 而不是Configurable 否则会添加失败
@Component [组件]
控制类端代码:
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
//1.先得到上下文对象
ApplicationContext context
= new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserController controller = context.getBean("userController", UserController.class);
controller.sayHi();
UserService service = context.getBean("userService", UserService.class);
service.sayHello();
UserRepository repository = context.getBean("userRepository",UserRepository.class);
repository.sayHi();
UserConfig config = context.getBean("userConfig",UserConfig.class);
config.sayHi();
UserComponent component = context.getBean("userComponent",UserComponent.class);
component.sayHi();
}
}
运行结果如下:
可以发现能够真正常运行, 那么, 如果不加注解会出现什么样的效果呢?
会出现运行异常 NoSuchBeanDefinitionException
错误信息
如果Bean对象并不在扫描的路径 会出现什么样的效果呢?
其实是同样的异常 ,没有找到bean定义的对象 . 因此,指定扫描路径以及添加注解非常重要.
此时还有一个问题:
五大注解都是能够添加Bean的, 那么他们的区别是什么?
为什么需要五大类注解?
让代码可读性高, 让程序员能够直观判断当前类的用途
- Controller 负责和前端数据的校验控制
- Service 就是负责数据的组装和接口的调用
- Resository就是和数据库进行交互的层面, 也就是DAO层
五大类注解的关系?
查看 Controller , Service , Respository ,Configuration 的源码:
我们发现,@Controller ,@Service @Configuration @Responsitory 都是基于@Component注解实现的,
因此 @Component 是其他4个注解的父类.
查看注解生成Bean name 的代码, 了解生成Bean name的机制
b) 通过@Bean 方法
创建一个User类
创建UserBeans类,用来存放User对象的方法
PS: ** bean是添加到方法上的,并且@Bean注解是不能单独存在的,需要五大注解**的加持
调用 当Context对象通过bean name 获取到对象的时候 就已经调用了该方法.
结果如下:
方法注解默认的Bean name 是 方法名, 但是也可以指定name(推荐) , 此时通过方法名获取Bean name这个方法就会失效
首先试着调用user1试试还会不会生效:
结果就是报错了 :
再使用指定的方法name 来获取Bean name :
结果如下:
成功获取到当前Bean方法的user对象了
2. 获取Bean对象
获取bean对象也叫做对象装配,是把对象取出来放到某个类中, 有时候也叫对象注入
对象装配(对象注入)的实现方法以下三种:(注入的三种方式)
1.1三种注入方式
属性注入(字段注入)
- 构造方法注入
Setter注入
属性注入,构造方法注入,setter注入的区别:
- 属性注入特点是写法简单, 但是通用性不好, 它只能运行在Ioc容器下,如果是非Ioc容器就会出现问题(空指针异常)
- Setter注入: 早期Spring版本推荐Setter注入,Setter注入通用性没有构造方法注入通用.
- 构造方法注入的好处:通用性更好,它能确保在注入对象之前, 此注入对象一定能被初始化,但是当注入方法注入参数过多时,此时开发者就需要检查自己写的代码是否符合单一设计原则的规范,此注入方式也是spring后期版本中推荐的注入方式.
1.2 两种注入方法
- @Resource
- @Aurowired
注入的两种方法的区别:
@Resource vs @Autowired
- 出身不同: @Resource 来自于Jdk , @Autowried 时 Spring 框架提供的
- 用法不同: @Autowired 支持属性注入,构造方法注入和Setter注入, 而 @Resource 不支持构造方法注入
- 支持参数不同: @Resource 支持更多的参数设置,(name,type 设置…),而 @Autowired 只支持 required 参数
2.1当 @Bean 将一个类型对象注入多次的问题
UserBeans类将对象User注入了两次:
App类中:如
ApplicationContext context
= new ClassPathXmlApplicationContext("spring-config.xml");
UserController controller = context.getBean("userController", UserController.class);
controller.sayHi();
此时就会报错: 也是因为 在UserController内部匹配到了两个User对象, 但是期望的时唯一一个
2.2 解决方案
方案1: 直接指定变量名和bean name 相同
方案2: 使用@Resource设置name / 使用@Autowired 搭配 @Qualifier value属性来指定注入对象:
使用@Resource设置name:
运行结果 :
匹配成功
还没有评论,来说两句吧...