创建对象的方式
23种设计模式之——工厂模式
目的:解耦(降低耦合度)
一.创建对象的方式
1.构造器的方法
javabean文件
package com.neuedu.homework1;
public class Student {
private String name;
private int age;
private String gender;
private String address;
public Student(){
System.out.println("构造器");
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
配置applicationContext.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">
<!-- Student构造器-->
<bean id="stu0" class="com.neuedu.homework1.Student">
<property name="name" value="构造器测试"/>
<property name="age" value="3"/>
<property name="gender" value="1"/>
<property name="address" value="tjnu"/>
</bean>
</beans>
2.静态工厂
javabean文件
package com.neuedu.homework1;
public class StuStaticFactor {
public static Student getInstance(){
Student stu=new Student();
stu.setName("静态工厂测试");
stu.setAge(1);
stu.setGender("1");
stu.setAddress("tjnu");
return stu;
}
}
配置applicationContext.xml文件
<!-- Student静态工厂-->
<bean id="stu1" class="com.neuedu.homework1.StuStaticFactor" factory-method="getInstance"/>
3.实例工厂
javabean文件
package com.neuedu.homework1;
public class StuInstanceFactor {
public Student getInstance() {
Student stu = new Student();
stu.setName("实例工厂测试");
stu.setAge(1);
stu.setGender("1");
stu.setAddress("tjnu");
return stu;
}
}
配置applicationContext.xml文件
<!-- Student实例工厂-->
<bean id="stu2" class="com.neuedu.homework1.StuInstanceFactor"/>
<bean id="stu2-1" factory-bean="stu2" factory-method="getInstance"/>
4.测试代码
import com.neuedu.entity.User;
import com.neuedu.homework1.Student;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StudentTest {
private static ApplicationContext applicationContext;
//加载配置文件,通过反射 创建配置文件里的对象=》注入属性值=》将该对象放入到Spring容器中
@Before
public void setup(){
applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testBean(){
Student stu0 = (Student) applicationContext.getBean("stu0");
System.out.println(stu0.getName());
// System.out.println(stu0.getGender());
// System.out.println(stu0.getAge());
// System.out.println(stu0.getAddress());
System.out.println("stu0:"+stu0);
Student stu1= (Student) applicationContext.getBean("stu1");
System.out.println(stu1.getName());
System.out.println("stu1:"+stu1);
Student stu2= (Student) applicationContext.getBean("stu2-1");
System.out.println(stu2.getName());
System.out.println("stu2:"+stu2);
}
}
5.单例模式
单例模式是指内存中只会创建且仅创建一次对象的设计模式.
参考文章: link
二.对象创建的时机
1.lazy-init属性
default/false->在spring容器启动的时候,创建对象(不延迟初始化)
true->在context.getBean时,创建对象(延迟初始化)
applicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化(也就是依赖注入).
提前实例化意味着作为初始化过程的一部分,applicationContext实例会创建并配置所有的singleton bean
通常情况下这是件好事,因为这样在配置中的任何错误就会立即被发现.
<!-- 懒加载(默认设置)-->
<bean id="student" class="com.neuedu.homework1.Student"/>
<!-- 该bean默认的设置为-->
<bean id="student" lazy-init="" class="com.neuedu.homework1.Student"/>
但是如果有一个bean中有一个属性,该属性含有大量的数据,这时候不希望该bean过早的停留在内存中怎lazy-init=“true”
<!-- 懒加载(context.getBean时加载)-->
<bean id="student" lazy-init="true" class="com.neuedu.homework1.Student"/>
2.scope作用域
scope属性
singleton->单例(默认设置)
prototype->多例
- 在默认情况下,放入到spring中的bean都是单例的
- 设置为prototype之后,就会创建多个实例,可以理解为会new很多次.而singleton只会new一个实例
applicationContext.xml
<!-- 对象scope的作用域-->
<bean id="student1" class="com.neuedu.homework1.Student" scope="singleton"></bean>
<bean id="student2" class="com.neuedu.homework1.Student" scope="prototype"></bean>
StudentTest测试代码
// scope="singleton"
Student student1 = (Student) applicationContext.getBean("student1");
Student student2 = (Student) applicationContext.getBean("student1");
System.out.println("student1:"+student1);
System.out.println("student2:"+student2);
// scope="prototype"
Student student3= (Student) applicationContext.getBean("student2");
Student student4= (Student) applicationContext.getBean("student2");
System.out.println("student3:"+student3);
System.out.println("student4:"+student4););
输出结果
说明: scope=“prototype” -> 只在Context.getBean时创建对象(lazy-init失效)
三.初始化和销毁方法
Student
public class Student(){
private String namel
private int age;
private String gender;
private String address;
public Student(){
System.out.println("Student构造器");
}
public void init(){
System.out.println("Student初始化方法");
}
public void destory(){
System.out.println("Student销毁方法");
}
applicationContext.xml
<!-- 初始化和销毁方法配置-->
<bean id="stu3" init-method="init" destroy-method="destory"
class="com.neuedu.homework1.Student"/>
StudentTest
// 销毁方法
ClassPathXmlApplicationContext application=
(ClassPathXmlApplicationContext) applicationContext;
application.close();
说明:
1.init方法是由spring内部执行的
2.destory方法 只有党spring容器关闭以后才会执行
3.如果一个bean的配置是scope=“prototype”,则spring容器不负责销毁
总结
利用了反射技术,其中,applicationContext.xml文件中的一个bean的id就相当于创建了一个对象
Spring容器什么时候产生的?
测试时,加载applicationContext.xml文件就会产生Spring容器
也就是下述代码的作用
//加载配置文件,通过反射 创建配置文件里的对象=》注入属性值=》将该对象放入到Spring容器中
@Before
public void setup(){
applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
}
反射机制通过类地址——去创建对象——一个bean的id就是创建了一个对象——创建的这个对象就放到hashmap中;当我们调用getBean(“user”)时(user就是bean的id)——getBean就会去hash容器里面取