一、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/beans
http://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是工厂完全独立在总部之外,而且可以开放给任何有生产需求方。