目录
1. 创建 Spring 项目
1.1 创建一个 maven 项目
1.2 添加 Spring 框架支持
1.3 添加启动类
2. 存储 Bean 对象
2.1 创建 Bean
2.2 将 Bean 注册到容器
3. 获取并使用 Bean 对象
3.1 创建 Spring 上下文
ApplicationContext 和 BeanFactory 的区别(重点)
3.2 获取指定的 Bean 对象
3.2.1 通过 id 获取
3.2.2 通过类型获取
3.2.3 通过 id + 类型 获取
3.3 使用 Bean
4. Spring 创建和使用总结
5. 根据日志定位问题
5.1 NoUniqueBeanDefinitionException -- 无唯一BeanDefinition异常
5.2 BeanDefinitionParsingException -- BeanDefinition解析异常
5.3 FileNotFoundException -- 文件未找到异常
5.4 NoSuchBeanDefinitionException -- 没有这样的对象
在上篇文章中,我们了解了 Spring 的核心与设计思想:Spring 是一个包含了众多工具方法的 IoC 容器。Spring 具备的两个功能:
在 Java 中,对象也叫 Bean。
接下来我们使用 maven 方式来创建一个 Spring 项目,分以下三步:
org.springframework
spring-context
5.2.3.RELEASE
org.springframework
spring-beans
5.2.3.RELEASE
添加以上代码后,刷新,显示如下图所示:
在创建好的项目 Java 文件夹下新创建一个包含 main 方法的启动类:
public class App {
public static void main(String[] args) {
}
}
存储 Bean 分以下两步:
所谓的 Bean 是Java 语言中的一个普通对象,实现代码如下:
public class User {
public String sayHi(String name){
return name + "Hi";
}
}
获取并使用 Bean 对象分为以下3步:
如果获取多个 Bean 则重复第2、3步骤。
ApplicationContext 可以认为是 Spring 的运行环境,翻译过来就是上下文。
使用 ApplicationContext 创建 Spring 的上下文对象,创建的时候需要配置 Spring 配置信息:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
除了 ApplicationContext 我们还可以使用 BeanFactory 来获取 Spring 的上下文:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
ApplicationContext 和 BeanFactory 效果是一样的,ApplicationContext 属于 BeanFactory 的子类,它们有以下区别:
CalssPathXmlApplicationContext 属于 ApplicationContext 的子类,拥有 ApplicationContext 的所有功能,是通过 xml 的配置来获取所有 Bean 的。
通过以下几种方法可以获取 Bean,最常用的为上面三种:
User user = (User)context.getBean("user"); // 通过 Id 获取
需要注意的是,Id 是唯一的,Bean 的 Id 需要一一对应:
// 通过类名获取
User user = context.getBean(User.class);
优点:不需要进行类型转换
缺点:如果一个类有多个对象时,不能使用该方式
// 通过 id + 类型获取
User user = context.getBean("user",User.class);
那么 通过类型获取 Bean 和 id + 类型 获取 Bean 有什么区别呢?
区别:当有⼀个类型被重复注册到 spring-config.xml 中时,只能使用根据名称获取了,比如以
错误日志:Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'BuildSpring.User' available: expected single matching bean but found 2: user,user2
可以看到错误日志大致为:期待找到一个匹配的 bean 但是 找到了两个分别是:user 和 user2.
User user = (User)context.getBean("user");
System.out.println(user);
User user1 = (User)context.getBean("user");
System.out.println(user1);
User user2 = context.getBean(User.class);
System.out.println(user2);
User user3 = context.getBean("user",User.class);
System.out.println(user3);
可以看到,无论获取多少次对象或者使用哪种方式获取,依然拿到的是同一个 Bean。
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
// 通过 ID 获取
User user = (User)context.getBean("user");
// 通过类名获取
// User user = context.getBean(User.class);
// 通过 id + 类型获取
// User user = context.getBean("user",User.class);
System.out.println(user.sayHi("小明"));
}
}
Spring 的创建和使用的整体流程为:
日志只有一段时只看一段的最前面就可以(从上往下看),当有多段时从下往上看。
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'BuildSpring.User' available: expected single matching bean but found 2: user,user2
期待找到一个匹配的 bean 但是找到了两个分别是:user 和 user2。
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'user' is already used in this
element
Offending resource: class path resource [spring-config.xml]
Bean名称“user”已在此<beans>元素路径资源[spring config.xml]中使用。
Caused by: java.io.FileNotFoundException: class path resource [spring-config1.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:331)
... 13 more
[spring-config1.xml]无法打开,因为它不存在。
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'user1' available
没有名为“user1”的bean可用。