<框架篇(2)>Spring框架中实例对象(bean)的创建方式(一)
2017-05-14 20:34
453 查看
在前一篇文章中简单的介绍了SpringIoc(依赖注入/控制反转)的原理及为什么要使用IoC,并且以一个简单的例子说明了在使用Spring框架时Bean的创建和使用的方式。事实上,Spring提供了丰富的创建实例Bean的方式,大致上可以分为:指定全类名、工厂方法、基于注解,文章先讲解通过指定全类名的方式创建Bean。
首先创建两个bean类,一个为Car.jave,另一个为Person.java,代码如下:
注意两个bean的不同,在Car.java中,有两个重载的带参构造方法,没有无参的构造方法,4个属性没有对应的getter和setter,因此只能通过两个带参构造方法实例化对象。而在Person.java中,所有的属性都有对应的getter和setter,并默认有无参的构造方法,这两种代表了我们在创建对象时的不同的方法,重写ToString()方法方便查看创建的实例对象。之所以把他们分开,是因为通过Spring Bean Configuration File来创建Bean的方式也是不同的。
一,Spring容器创建Car实例
通过此种方法创建Car实例时,Spring容器会找到cn.pb.bean.Car类中的带参的构造方法并为参数赋值,创建Car对象,为了避免顺序混乱,也可以如下写:
可能你还会有疑问,在Car.java中有两个带参的构造方法,他们的第三个参数是不同的,它找的是哪一个呢?可先输出下结果,测试代码如下:
输出结果:
可以看出,默认的是第一个构造方法,这与Car中构造方法的顺序有关。同时要注意,Spring会自动将int型转换为double,却不会将idouble转换为int,因此即使将构造方法Car(String brand, String local, int maxSpeed)置于前面,当constructor-arg标签index=”2”的项值设置为double型,创建的也是Car(String brand, String local, double price)对象。为了避免出现不必要的错误,可添加type属性:
此时就可以根据类型创建对应的对象,以区分重载的构造方法,注意type值得字母大小写与类型的对应顺序,否则会报错。
也可以将value属性提出来放在一个单独的标签中,当值中出现特殊字符如”>”、”<”时会报错,此时可以用
实例化结果:
二,Spring容器创建Person实例
实例化结果:
用此种方法创建实例实际上是通过无参的构造方法来创建对象,通过每个属性所对应的setter方法类进行赋值的,因此在Person类中必须有无参的构造方法和对应的setter,同时应该注意property节点中name属性的值要与set方法后的名字一致,例如:name=”age”,在Person中的方法是setAge(int age),因为是通过反射机制来进行赋值的。此对象中有一个属性是对对象car的引用,因此也可以如下写:
创建的过程还有一种简化写法,首先在xml中引入p命名空间,则person还可以改写为:
三,在此之外还有自动装配的方法,可以使用autowire属性指定自动装配的方式,byName根据bean的id名称和当前bean的setter风格的属性名进行自动装配 ,例如:
实例化结果:
因为在Person类中是setCar,所以这里会自动装配id名称为car的Bean,而不会装配id名称为car1的Bean。
byType则根据bean的类型当前bean的属性类型进行自动装配,若IoC容器中有1个以上的类型匹配的bean则抛出异常,如:
此时会抛出异常,因为创建创建了id=”car”和id=”car1”两个Car类型的实例,注掉其中一个如注掉car1,则实例化结果:
以上介绍了Spring中Bean的创建方式,特别的,如果两个实例之间存在继承关系,比如id=”person3”的实例与id=”person”实例对象的属性除姓名之外都一样,则可以使用bean的parent属性指定继承哪个bean的属性,创建person3的语句可以如下写:
id=”person”实例:
id=”person3”实例:
当指定的bean中有autowire属性时,将不会继承该属性。给bean添加属性abstract=”true”,则此bean只能用来被继承而不能被IoC实例化 ,若某个bean的class属性没有指定,则该bean必须是一个抽象bean。
首先创建两个bean类,一个为Car.jave,另一个为Person.java,代码如下:
package cn.pb.bean; public class Car { private String brand; private String local; public double price; private int maxSpeed; public Car(String brand, String local, double price) { super(); this.brand = brand; this.local = local; this.price = price; } public Car(String brand, String local, int maxSpeed) { super(); this.brand = brand; this.local = local; this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car [brand=" + brand + ", local=" + local + ", price=" + price + ", maxSpeed=" + maxSpeed + "]"; } }
package cn.pb.bean; public class Person { private String name; private int age; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } }
注意两个bean的不同,在Car.java中,有两个重载的带参构造方法,没有无参的构造方法,4个属性没有对应的getter和setter,因此只能通过两个带参构造方法实例化对象。而在Person.java中,所有的属性都有对应的getter和setter,并默认有无参的构造方法,这两种代表了我们在创建对象时的不同的方法,重写ToString()方法方便查看创建的实例对象。之所以把他们分开,是因为通过Spring Bean Configuration File来创建Bean的方式也是不同的。
一,Spring容器创建Car实例
<bean id="car" class="cn.pb.bean.Car"> <constructor-arg value="Audi"></constructor-arg> <constructor-arg value="shanghai"></constructor-arg> <constructor-arg value="3000000"></constructor-arg> </bean>
通过此种方法创建Car实例时,Spring容器会找到cn.pb.bean.Car类中的带参的构造方法并为参数赋值,创建Car对象,为了避免顺序混乱,也可以如下写:
<bean id="car" class="cn.pb.bean.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="shanghai" index="1"></constructor-arg> <constructor-arg value="3000000" index="2"></constructor-arg> </bean>
可能你还会有疑问,在Car.java中有两个带参的构造方法,他们的第三个参数是不同的,它找的是哪一个呢?可先输出下结果,测试代码如下:
package cn.pb.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.pb.bean.Car; public class ConfigurationTest { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("ConfigurationTest.xml"); Car car=(Car) ctx.getBean("car"); System.out.println(car); } }
输出结果:
Car [brand=Audi, local=shanghai, price=3000000.0, maxSpeed=0]
可以看出,默认的是第一个构造方法,这与Car中构造方法的顺序有关。同时要注意,Spring会自动将int型转换为double,却不会将idouble转换为int,因此即使将构造方法Car(String brand, String local, int maxSpeed)置于前面,当constructor-arg标签index=”2”的项值设置为double型,创建的也是Car(String brand, String local, double price)对象。为了避免出现不必要的错误,可添加type属性:
<bean id="car" class="cn.pb.bean.Car"> <constructor-arg value="Audi" type="String"></constructor-arg> <constructor-arg value="shanghai" type="String"></constructor-arg> <constructor-arg value="300000" type="double"></constructor-arg> </bean>
此时就可以根据类型创建对应的对象,以区分重载的构造方法,注意type值得字母大小写与类型的对应顺序,否则会报错。
也可以将value属性提出来放在一个单独的标签中,当值中出现特殊字符如”>”、”<”时会报错,此时可以用
<bean id="car1" class="cn.pb.bean.Car"> <constructor-arg> <value><![CDATA[>BMW<]]></value> </constructor-arg> <constructor-arg value="guangzhou"></constructor-arg> <constructor-arg type="int"> <value>290</value> </constructor-arg> </bean>
实例化结果:
Car [brand=>BMW<, local=guangzhou, price=0.0, maxSpeed=290]
二,Spring容器创建Person实例
<bean id="person" class="cn.pb.bean.Person"> <property name="name" value="zhangsan"></property> <property name="age" value="24"></property> <property name="car"> <bean class="cn.pb.bean.Car"> <constructor-arg value="Audi" type="String"></constructor-arg> <constructor-arg value="shanghai" type="String"></constructor-arg> <constructor-arg value="300000" type="double"></constructor-arg> </bean> </property> </bean>
实例化结果:
Person [name=zhangsan, age=24, car=Car [brand=Audi, local=shanghai, price=300000.0, maxSpeed=0]]
用此种方法创建实例实际上是通过无参的构造方法来创建对象,通过每个属性所对应的setter方法类进行赋值的,因此在Person类中必须有无参的构造方法和对应的setter,同时应该注意property节点中name属性的值要与set方法后的名字一致,例如:name=”age”,在Person中的方法是setAge(int age),因为是通过反射机制来进行赋值的。此对象中有一个属性是对对象car的引用,因此也可以如下写:
<bean id="person" class="cn.pb.bean.Person"> <property name="name" value="zhangsan"></property> <property name="age" value="24"></property> <property name="car"> <ref bean="car"/> </property> </bean>
创建的过程还有一种简化写法,首先在xml中引入p命名空间,则person还可以改写为:
<bean id="person" class="cn.pb.bean.Person" p:age="24" p:name="zhangsan" p:car-ref="car"></bean>
三,在此之外还有自动装配的方法,可以使用autowire属性指定自动装配的方式,byName根据bean的id名称和当前bean的setter风格的属性名进行自动装配 ,例如:
<bean id="person2" class="cn.pb.bean.Person" p:age="30" p:name="Cendy" autowire="byName"></bean>
实例化结果:
Person [name=Cendy, age=30, car=Car [brand=Audi, local=shanghai, price=300000.0, maxSpeed=0]]
因为在Person类中是setCar,所以这里会自动装配id名称为car的Bean,而不会装配id名称为car1的Bean。
byType则根据bean的类型当前bean的属性类型进行自动装配,若IoC容器中有1个以上的类型匹配的bean则抛出异常,如:
<bean id="person2" class="cn.pb.bean.Person" p:age="30" p:name="Cendy" autowire="byType"></bean>
此时会抛出异常,因为创建创建了id=”car”和id=”car1”两个Car类型的实例,注掉其中一个如注掉car1,则实例化结果:
Person [name=Cendy, age=30, car=Car [brand=Audi, local=shanghai, price=300000.0, maxSpeed=0]]
以上介绍了Spring中Bean的创建方式,特别的,如果两个实例之间存在继承关系,比如id=”person3”的实例与id=”person”实例对象的属性除姓名之外都一样,则可以使用bean的parent属性指定继承哪个bean的属性,创建person3的语句可以如下写:
<bean id="person3" p:name="Tom" parent="person"></bean>
id=”person”实例:
Person [name=zhangsan, age=24, car=Car [brand=Audi, local=shanghai, price=300000.0, maxSpeed=0]]
id=”person3”实例:
Person [name=Tom, age=24, car=Car [brand=Audi, local=shanghai, price=300000.0, maxSpeed=0]]
当指定的bean中有autowire属性时,将不会继承该属性。给bean添加属性abstract=”true”,则此bean只能用来被继承而不能被IoC实例化 ,若某个bean的class属性没有指定,则该bean必须是一个抽象bean。
相关文章推荐
- JSP动作标签useBean--<jsp:useBean> 创建一个对象
- SSH(Struts2+Spring+Hibernate)框架搭建流程<注解的方式创建Bean>
- Js初学笔记之<创建对象的五种方式>
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- 让<未将对象引用到实例>见鬼去吧!
- Bean实例的创建方式及依赖配置
- Android Layout研究 <三> View的布局方式及实例
- IE6通过点击 <a href="javascript:void(0);"></a>方式动态创建iframe无法显示
- 快速创建 IEqualityComparer<T> 和 IComparer<T> 的实例
- [DIOCP3/MyBean/QDAC开源项目] DataModule-DB例子基于MyBean的插件实例<三层数据库方案>
- 7.7.3: Bean实例的创建方式及依赖配置---调用实例工厂方法创建Bean
- 7.7.1: Bean实例的创建方式及依赖配置---使用构造器创建Bean实例
- spring内部创建对象的方式(或bean实例化方式)
- 7.7.2: Bean实例的创建方式及依赖配置---使用静态工厂方法创建Bean
- 快速创建 IEqualityComparer<T> 和 IComparer<T> 的实例
- ASP.NET小收集<8>:JS创建对象
- webkit的js对象扩展(一)——binding方式创建自定义对象(单实例)
- webkit的js对象扩展(一)——binding方式创建自定义对象(单实例)
- < Unity 3D专栏 >动态创建对象,并渲染贴图,动态添加删除脚本
- 快速创建 IEqualityComparer<T> 和 IComparer<T> 的实例