如何将Spring6工厂设计模式与Bean实例化方式结合为一个?

摘要:bean的作用域 ioc容器默认bean是单例的(singleton)。 bean对象的创建是在初始化上下文的时候就创建了,每一次调用getBean()时,都返回那个单例对象。这行代码会创建配置里面的bean对象 Applicati
bean的作用域 ioc容器默认bean是单例的(singleton)。 bean对象的创建是在初始化上下文的时候就创建了,每一次调用getBean()时,都返回那个单例对象。 // 这行代码会创建配置里面的bean对象 ApplicationContext context = new FileSystemXmlApplicationContext("D:/applicationContext.xml"); 那如何把bean设置成多例的? <!-- scope="prototype" 会使这个bean变成多例的--> <bean id="sb" class="com.ali.bean.SpringBean" scope="prototype"/> // 由于这个bean是多例模式,这行代码不会创建bean对象。而是在调用getBean()时创建对象 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml","spring-dao.xml"); // 这行代码才会创建bean对象 Object user= context.getBean("sb"); <!-- scope="prototype" 会使这个bean变成多例的 目前scope有2个值:singleton 和 prototype 当项目引入spring-webmvc依赖变成web项目时,scope会多2个属性 request:表示每次http请求都会创建一个新的bean对象 session: 表示每次 session都会创建一个新的bean对象 --> <bean id="sb" class="com.ali.bean.SpringBean" scope="prototype"/> 自定义scope 自定义Scope(实现Scope接口) spring内置了线程范围类: org.springframework.context.support.SimpleThreadScope 添加配置信息 <bean id="sb" class="com.ali.bean.SpringBean" scope="threadScope"/> <!-- 配置自定义的作用域,实现一个线程一个bean--> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer" > <property name="scopes"> <map> <entry key="threadScope"> <!-- 这个SimpleThreadScope 是spring框架内置的,也可以自定义--> <bean class="org.springframework.context.support.SimpleThreadScope"></bean> </entry> </map> </property> </bean> GoF之工厂模式 工厂模式的三种形态 简单工厂模式(Simple Factory):又叫静态工厂方法模式。是工厂方法模式的一种特殊实现。 工厂方法模式 (Factory Method) 抽象工厂模式 (Abstract Factory) 简单工厂模式 简单工厂模式包括三个角色:抽象产品、具体产品、工厂类。代码如下: 抽象产品类 // 抽象产品角色 public abstract class Weapon { public abstract void attack(); } 具体产品 // 具体产品角色:匕首 public class Dagger extends Weapon{ @Override public void attack() { System.out.println("匕首攻击..."); } } // 具体产品角色:战斗机 public class Fighter extends Weapon{ @Override public void attack() { System.out.println("战斗机攻击..."); } } // 具体产品角色:坦克 public class Tank extends Weapon{ @Override public void attack() { System.out.println( "坦克攻击。。。"); } } 工厂类角色 // 工厂类角色 public class WeaponFactory { /** * 静态方法:根据传入的参数获取相应的武器 * @return */ public static Weapon get(String type){ switch (type){ case "Tank": return new Tank(); case "Fighter": return new Fighter(); case "Dagger": return new Dagger(); default: return null; } } } 测试代码: public class Main { public static void main(String[] args) { // 简单工厂模式达到职责分离。客户端不关心产品生产的细节 // 客户端只负责消费,工厂类负责生产。这就是简单工厂模式的作用。 Weapon weapon1 = WeaponFactory.get("Tank"); weapon1.attack(); Weapon weapon2 = WeaponFactory.get("Fighter"); weapon2.attack(); Weapon weapon3 = WeaponFactory.get("Dagger"); weapon3.attack(); } } 优缺点: 优点:实现职责分离。 缺点:假如要添加新产品。需要修改工厂类代码。显然违反了ocp原则。 ​ 工厂类责任重大。一旦瘫痪,这个系统必然瘫痪。 工厂方法模式 工厂方法模式保留了简单工厂模式的优点。同时解决了简单工厂模式的缺点。 解决方法是:一个工厂对应一个产品。符合ocp原则。 优点:扩展性高。要想增加一个产品。只要扩展一个工厂类就可以。 屏蔽产品具体实现。调用者只关心产品的接口。 缺点:会使类的数量成倍增加,增加系统复杂度。 工厂方法模式的角色包括: 抽象工厂角色 具体工厂角色 抽象产品角色 具体产品角色 代码如下: // 抽象产品角色 public abstract class Weapon { public abstract void attack(); } // 具体产品角色:匕首 public class Dagger extends Weapon { @Override public void attack() { System.out.println("匕首攻击..."); } } // 具体产品角色:枪械 public class Gun extends Weapon{ @Override public void attack() { System.out.println("枪械攻击..."); } } // 抽象工厂类 public abstract class WeaponFactory { public abstract Weapon get(); } // 具体工厂类:匕首工厂 public class DaggerFactory extends WeaponFactory{ @Override public Weapon get() { return new Dagger(); } } // 具体工厂类:枪械工厂 public class GunFactory extends WeaponFactory{ @Override public Weapon get() { return new Gun(); } } 测试代码: public static void main(String[] args) { WeaponFactory weaponFactory = new DaggerFactory(); Weapon dagger = weaponFactory.get(); dagger.attack(); WeaponFactory weaponFactory1 = new GunFactory(); Weapon gun = weaponFactory1.get(); gun.attack(); } bean的实例化 spring为bean提供了多种实例化的方式,通常包括4种方式。 通过构造方法实例化 通过简单工厂模式实例化 通过factory-bean实例化 通过FactoryBean接口实例化 通过构造方法实例化 <!-- spring会自动调用该类的无参数构造方法来实例化对象,这个SpringBean类必须有一个无参数的构造方法--> <bean id="springBean" class="com.ali.bean.SpringBean" /> 通过简单工厂模式实例化 // 工厂类 public class StarFactory { public static Star createStar() { return new Star(); } } <!-- 静态(简单)工厂方法实例化bean 指定调用哪个类的哪个方法。这里实例化的是Star对象。 factory-method 指定的是工厂类中的静态方法名称。 --> <bean id="starBean" class="com.ali.bean.StarFactory" factory-method="createStar"></bean> 通过factory-bean实例化 // 工厂方法模式中的具体产品类 public class Gun { public Gun() { System.out.println("无参数构造器:Gun()"); } } // 工厂方法模式中的具体工厂类 public class GunFactory { public Gun get(){ return new Gun(); } } <!-- 通过工厂方法模式实例化bean。由factory-bean指定工厂类的bean id,factory-method指定工厂类中的实例方法名称--> <bean id="gunFactory" class="com.ali.bean.GunFactory"></bean> <bean id="gun" factory-bean="gunFactory" factory-method="get"></bean> 通过FactoryBean接口实例化 通过factory-bean实例化的方式需要我们自定义factory-bean和factory-method。 在spring中,当自己的类实现了FactoryBean接口后factory-bean和factory-method就不需要指定了。factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。 public class PersonFactoryBean implements FactoryBean<Person> { @Override public Person getObject() throws Exception { // 手动创建对象 return new Person(); } @Override public Class<?> getObjectType() { return null; } } <!--PersonFactoryBean实现了FactoryBean接口,Spring会调用它的getObject方法来实例化person对象 不用写factory-bean和factory-method,直接将PersonFactoryBean配置为一个普通的bean即可 这样spring会自动调用PersonFactoryBean的getObject方法来实例化person对象--> <bean id="person" class="com.ali.bean.PersonFactoryBean"></bean> BeanFactory和FactoryBean的区别 BeanFactory:spring ioc容器的顶级对象,负责创建bean对象。BeanFactory是工厂 FactoryBean:本质是一个bean。能够辅助spring实例化其他bean对象。