Spring中bean对象带参数注入的三种方式以及Spring框架找不到bean xml:FileNotFoundException问题
一、Spring中bean对象带参数注入的三种方式
在往spring IOC容器注入对象时,如果都是使用隐式的无参构造,直接<bean id=.. class=.. > 如果要注入的对象是带参数实例化的例时,这时可以采用三种办法实现。这部分内容在spring官方文档:Redirecting... 的Constructor argument type matching位置部分 publish:September 28, 2020 -Monday。
先我们定义一个class,比如定义一个计算机类,有两个属性:品牌brank和size尺寸。
package cn.hellomaven;public class Computer {private String brank;private int Size;//带参数构造public Computer(String brank, int size) {super();this.brank = brank;Size = size;}public String getBrank() {return brank;}public void setBrank(String brank) {this.brank = brank;}public int getSize() {return Size;}public void setSize(int size) {Size = size;}
}
添加我们的java测试例,调用spring容器取得computer类。
package cn.hellomaven;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.kermit.test.Computer;public class Params {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");Computer computer = (Computer) context.getBean("computer");System.out.println(computer.toString());}
}
Spring中的注入Bean的相关配置如下:
#ApplicationContext.xml配置中的注入配置
<bean id="computer" class="cn.kermit.test.Computer" ></bean>
这时如果ApplicationContext.xml中注入Computer类中如果使用上面的写法就会报错,因为Computer类没有不带参数的实例化的方法,报错内容示例如下:
org.springframework.context.support.AbstractApplicationContext refresh 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'computer' defined in class path resource [ApplicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'computer' defined in class path resource [ApplicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
此时有以下三种方法来完成有参数的类的实例化。
第1种:根据参数的顺序索引来注入参数
#ApplicationContext.xml配置
<bean id="computer" class="cn.kermit.test.Computer" ><constructor-arg index="0" value="IBM"></constructor-arg><constructor-arg index="0" value="17寸"></constructor-arg>
</bean>
第2种:使用类型来注入,type是参数的类型。
但这种方法在有两个相同类型的参数时就不能用了。
<bean id="computer" class="cn.kermit.test.Computer" ><constructor-arg type="java.lang.String" value="IBM" /><constructor-arg type="int" value="17" />
</bean>
第3种:使用name指定参数名再赋值。
这个方法最实用
<bean id="computer" class="cn.kermit.test.Computer" ><constructor-arg name="brank" value="IBM" /><constructor-arg name="size" value="17" />
</bean>
运行结果如下:
#运行结果:
#Computer [brank=IBM品牌, Size=17]
二、Spring框架找不到bean xml:FileNotFoundException问题
Spring框架找不到bean xml:FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exist 。 publish:September 28, 2020 -Monday
IOC(invension of control)和AOP是Spring框架的核心特点,新建maven项目填写如下配置到pom.xml中自动导入spring框架的包依赖后。
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.10.RELEASE</version>
</dependency>
创建一个包,在包下面创建一个类如SpringTest,代码如下:
package cn.hellomaven;
public class SpringTest {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void show(){System.out.println("Hello,"+ name );}
}
然后我们开始配置beans.xml。对于这个文件名,怎么定义都没有问题的,但存放路径有所讲究,我之前把它放在默认的src下面,以及放在src/test下面都碰到了报错
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [beans.xml]; nested exception is java.io.FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exist at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:345)。
即找不到配置文件,但这个报错也很不友好,你找不到配置文件可以把你找了哪些路径列出来啊!后来摸索发现需要放在顶目目录src/main/resources下面。beans.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="SpringTest" class="cn.hellomaven.SpringTest"><property name="name" value="Spring"/></bean>
</beans>
最后我们写一个test.java来测试spring框架的IOC,test.java的代码如下:
package cn.hellomaven;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//getBean : 参数即为spring配置文件中bean的id .SpringTest hello = (SpringTest) context.getBean("SpringTest");hello.show();}
}
运行即成功调用SpringTest 类中的show方法,spring会将beans.xml中配置的各个bean(实际就是对应一个java class)实例化,如此spring也就成了一个IOC容器。因为里面装载着我们配置好的全部对象,需要哪个我们只需要通过getBean方法来取得对象。看着bean就是像一个工厂模式,只是程序开发中的工厂模式工厂都在自己的程序代码里,而java中的bean是工厂完全独立在总部之外,而且可以开放给任何有生产需求方。