1.实例化bean指的是,当ioc容器获取到配置文件时,对配置文件中bean标签的一种解析,容器通过bean标签的id属性确认bean的位置
2.三种方式: 类构造器实例化bean(最为常用的)
实例化工厂创建bean实例
静态工厂创建bean实例
3.话不多说,看代码!!!
3.1类构造器实例化bean()
定义一个主类
public class bean {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="person" class="class_init.bean">
<property name="id" value="1"></property>
<property name="name" value="珀布利"></property>
</bean>
</beans>
测试类
package class_init;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("class_init.xml");
bean b=(bean) ac.getBean("person");
System.out.println(b.getId());
System.out.println(b.getName());
}
}
总结:类构造器初始化bean是三者中最为简单的,所以也最为常用,它简便不像工厂方法初始化bean,必须有个工厂类也有<constructor-args>标签.
但是有点让我想不通的是它的名字为什么叫做类构造器初始化bean?
于是我为了寻找这个名字的意义:我去用构造方法加参数,然后初始化bean突然发现我在构造方法加参数这不过是构造方法注值方式而已,和set方法是一样的,所以,我的结论是:类构造器初始化参数仅仅是利用application去初始化一个bean,该过程就叫类构造初始化bean;而如果你在后台添加了工厂方法和静态工厂方法那么就叫做实例化工厂创建bean和静态方法创建bean
2.实例化工厂创建bean实例(主要看配置)
(我们先拟定需求--->得到农场物语矿石镇里养鸡少年的名字及爱好,和我玩的那位玩家的喜好)
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="factory" class="instance_test.factory"/>
<bean id="sam" factory-bean="factory" factory-method="getperson">
<constructor-arg value="sam"></constructor-arg>
</bean>
<bean id="akefu" factory-bean="factory" factory-method="getperson">
<constructor-arg value="akefu"></constructor-arg>
</bean>
</beans>
人物设定: 阿克夫 和 sam(玩家)
定义一个总的人类模板
package instance_test;
public interface Person {
String eat(String food);
String likePerson(String girl);
}
sam玩家定义
package instance_test;
public class sam implements Person{
public String eat(String food) {
// TODO Auto-generated method stub
return "sam喜欢的食品:"+food;
}
public String likePerson(String girl) {
// TODO Auto-generated method stub
return "sam喜欢的女孩:"+girl;
}
public String toString() {
return "sam [getClass()=" + getClass() + ", hashCode()=" + hashCode()
+ ", toString()=" + super.toString() + "]";
}
}
阿克夫人类定义
package instance_test;
public class akefu implements Person{
public String eat(String food) {
// TODO Auto-generated method stub
return "阿克夫喜欢的食品:"+food;
}
public String likePerson(String girl) {
// TODO Auto-generated method stub
return "阿克夫喜欢的女孩:"+girl;
}
public String toString() {
return "akefu [getClass()=" + getClass() + ", hashCode()=" + hashCode()
+ ", toString()=" + super.toString() + "]";
}
角色转换工厂
package instance_test;
public class factory {
public Person getperson(String str) {
if(str.equalsIgnoreCase("sam")){
return new sam();
// TODO Auto-generated method stub
}else{
return new akefu();
}
}
}
其实你应该可以注意到,实例化初始化bean是一个构造注入的方法来完成它的反射
测试类:
package instance_test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("instance_test.xml");
Person p=(Person) ac.getBean("sam");
System.out.println(p.eat("包子"));
System.out.println(p.likePerson("珀布利"));
Person p2=(Person) ac.getBean("akefu");
System.out.println(p2.eat("鸡饲料"));
System.out.println(p2.likePerson("多莲"));
}
}
总结: 反射的步骤: 先从测试类出发 由getbean得到sam标识进入 <bean id="sam" factory-bean="factory" factory-method="getperson"> 得到 factory 标识 再进入 <bean id="factory" class="instance_test.factory"/> 已进入到了工厂类对象,再由工厂类中的构造对象获取外界的数据 "sam"角色,则返回sam对象,把sam对象的方法返回,如不是,则返回阿克夫对象,阿克夫对象的方法返回.
配置中: id是外部容器访问的标识:即 applicationcontext ac=new classpathxmlapplicationcontext("bean.xml");
ac.getbean("bean");//此处id发挥作用,让容器找到bean配置并开始解析它
factory-bean 实例化工厂独特的地方 即寻找真正的工厂实例的id 它将工厂和两个将生产出来的产品分开来
factory-method 寻找工厂方法
<bean id="factory" class="instance_test.factory"/>
<bean id="sam" factory-bean="factory" factory-method="getperson">//此处的sam是 getbean中得到反射的sam对象,从而映射factory bean---->instance_test.factory
<constructor-arg value="sam"></constructor-arg> //此处是等价于instance_test.factory里的有参构造里的参数 public Person getperson(String str){ if(str.equalsingnorecase("sam")){ return new sam();} else{ return new akefu(); } }
</bean>
<bean id="akefu" factory-bean="factory" factory-method="getperson">
<constructor-arg value="akefu"></constructor-arg> //此处道理同上
</bean>
3.静态工厂方法实例化bean
配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="chin" factory-method="getperson" class="three.PersonFactory">
<constructor-arg value="chinese"></constructor-arg>
</bean>
<bean id="usa" factory-method="getperson" class="three.PersonFactory">
<constructor-arg value="usa"></constructor-arg>
</bean>
</beans>
3.1静态实例化Bean 对比下实例化工厂和静态工厂的区别:就是缺少一个factory-bean.
那么为什么会缺少了?原因在于,人家静态工厂通过class来定位构造函数的位置,不需要通过工厂bean再分配到被一个实例bean里面去
所以静态工厂相对来说比较独立..
再来看工厂方法也有别于实例化工厂的方法
3.2设定使用获取 猫爱吃鱼 独处 狗爱吃骨头 群居
3.3动物模板类
package static_tets;
public interface Animal {
String eat(String food);
String hobbits(String like);
}
猫
package static_tets;
public class cat implements Animal{
private String height;
public void setHeight(String height) {
this.height = height;
}
public void height() {
System.out.println("猫的体重:"+height);
}
public String eat(String food) {
// TODO Auto-generated method stub
return "猫爱吃:"+food;
}
public String hobbits(String like) {
// TODO Auto-generated method stub
return "猫喜欢:"+like;
}
}
狗
package static_tets;
public class dog implements Animal {
private String height;
public void setHeight(String height) {
this.height = height;
}
public void height() {
System.out.println("狗的体重:"+height);
}
public String eat(String food) {
return "狗爱吃:"+food;
}
public String hobbits(String like) {
return "狗喜欢:"+like;
}
}
猫狗转换工厂
package static_tets;
public class Animal_shop {
public static Animal getanimal(String str) {
if(str.equalsIgnoreCase("dog")){
return new dog();
}else{
return new cat();
}
}
}
测试类
package static_tets;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("static_test.xml");
dog an=(dog) ac.getBean("dog");
System.out.println(an.eat("骨头"));
System.out.println(an.hobbits("群居"));
an.height();
cat an1=(cat) ac.getBean("cat");
System.out.println(an1.eat("鱼"));
System.out.println(an1.hobbits("独处"));
an1.height();
}
}
配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="dog" class="static_tets.Animal_shop" factory-method="getanimal">
<constructor-arg value="dog"></constructor-arg>
<property name="height" value="40公斤"></property>
</bean>
<bean id="cat" class="static_tets.Animal_shop" factory-method="getanimal">
<constructor-arg value="cat" ></constructor-arg>
<property name="height" value="10公斤"></property>
</bean>
</beans>
4.总结:静态工厂实例化和实例化工厂方法区别在于配置上--->静态配置没有总工厂bean 实例化有一个总工厂bean来且提供了id
工厂方法中除了是静态以外,其他的都和实例化工厂一致(毕竟静态工厂的配置是直接通过类来找方法的,这样的写法不正是静态方法吗?)
又有人问:那么bean什么时候实例化了?
这是要分情况来看的
有两种情况:第一种如果采用了工厂方法实例化(你别管静态还是非静态) 第二种是采用了类构造器实例化
第一种情况,因为工厂方法都是通过实例化类来达到分配角色的方法来达到目的,所以当你调用对象时,工厂方式下才会对该bean进行实例化
第二种情况,类构造器实例化Bean,这种情况又分两种情况进行讨论: 第一:当scope="单例"时,则初始化容器时会对所有单例bean(包括单例里的多例)进行了实例化,理所当然你可以通过lazy-init="true"来规避这种情况(即使用懒加载),
第二:scope="多例"(prototype),则当调用到该bean才会实例化该bean,但是你不要忘了,多例情况下,每次初始化而且调用对象时,它都会产生一个新对象,容器产生完后便不再管理多例的生命周期了!