工厂模式的思想正好契合Spring IoC的设计思想:某一接口的具体具体实现类的选择权从调用类中移除,转而交给第三方决定,即借由Spring的Bean配置来实现控制,这同样也是工厂模式的思想。
工厂模式提供了一种绝佳的创建对象的方法。在工厂模式中我们并不会直接使用new来创建一个对象,而是使用一个共同的接口类来指定其实现类,这就大大降低了系统的耦合性——我们无需改变每个调用此接口的类,而直接改变实现此接口的类即可完成软件的更新迭代。
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
依赖关系
- 继承MessageSource,因此支持国际化;
- 统一的资源文件访问方式;
- 提供在监听器中注册Bean的事件;
- 同时加载多个配置文件;
- 载入多个(有继承关系)的上下文,使得每一个上下文都专注于一个特定的层次,比如应用的Web层。
加载方式
创建方式
注册方式
依赖注入是当前比较流行的IoC实现方式,依赖注入分为接口注入(Interface Injection),Setter方法注入(Setter Injection),构造器注入(Constructor Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4已被废除。
构造函数注入 | setter方法注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
任意修改都会创建一个新实例 | 任意修改不会创建一个新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
package com.spring.dao;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:22:50
*/
public interface Human {
/**
* 吃
*/
void eat();
/**
* 睡
*/
void sleep();
}
package com.spring.dao.impl;
import com.spring.dao.Human;
import com.spring.dao.Language;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:24:00
*/
public class Chinese implements Human {
@Override
public void eat() {
System.out.println("中国人吃吃吃吃吃");
}
@Override
public void sleep() {
System.out.println("中国人睡睡睡睡睡");
}
}
package com.spring.dao.impl;
import com.spring.dao.Human;
import com.spring.dao.Language;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:24:18
*/
public class American implements Human {
@Override
public void eat() {
System.out.println("美国人吃吃吃吃吃");
}
@Override
public void sleep() {
System.out.println("美国人睡睡睡睡睡");
}
}
package com.spring.test;
import com.spring.dao.Human;
import com.spring.dao.impl.American;
import com.spring.dao.impl.Chinese;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:25:22
*/
public class Test1 {
public static void main(String[] args) {
/**
* 传统方式:直接创建
* 缺点:
* 高耦合、可扩展性差、不够灵活
*/
Human human1 = new Chinese();
human1.eat();
human1.sleep();
Human human2 = new American();
human2.eat();
human2.sleep();
}
}
package com.spring.staticProxy;
import com.spring.dao.Human;
import com.spring.dao.impl.American;
import com.spring.dao.impl.Chinese;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:31:26
*/
public class HumanFactoryBean{
/**
* 代理工厂类
* @param name
* @return
*/
public Human getHuman(String name){
if("ch".equals(name)){
return new Chinese();//返回中国人实例
}else if("am".equals(name)){
return new American();//返回美国人实例
}else {
throw new IllegalArgumentException("参数语法错误!!!");
}
}
}
package com.spring.test;
import com.spring.dao.Human;
import com.spring.staticProxy.HumanFactoryBean;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:33:23
*/
public class Test2 {
public static void main(String[] args) {
/**
* 使用工厂模式管理实例创建
* 相比传统直接创建方式的优点:
* 解耦合、可扩展性高、灵活性高
*/
//创建工厂类对象
HumanFactoryBean humanFactory = new HumanFactoryBean();
Human human1 = humanFactory.getHuman("ch");//返回中国人实例对象
human1.eat();
human1.sleep();
Human human2 = humanFactory.getHuman("am");//返回美国人实例对象
human2.eat();
human2.sleep();
}
}
<?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">
<!--引入Chnise类-->
<bean id="ch" class="com.spring.dao.impl.Chinese"/>
<!--引入American类-->
<bean id="am" class="com.spring.dao.impl.American"/>
</beans>
package com.spring.test;
import com.spring.dao.Human;
import javafx.application.Application;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Base64;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:38:59
*/
public class Test3 {
public static void main(String[] args) {
/**
* 采用Spring的bean工厂方式创建实例
*/
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("src/applicationContext.xml"));
Human human1 = (Human) beanFactory.getBean("ch");
human1.eat();
human1.sleep();
Human human2 = (Human)beanFactory.getBean("am");
human2.eat();
human2.sleep();
/**
* 采用应用程序上下文方式创建bean实例
*/
//绝对路径(不推荐使用)
//ApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/applicationContext.xml");
//相对路径
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Human human3 = (Human) applicationContext.getBean("ch");
human3.eat();
human3.sleep();
Human human4 = (Human)applicationContext.getBean("am");
human4.eat();
human4.sleep();
}
}
package com.spring.dao;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 16:12:47
*/
public interface Language {
/**
* 语种
* @return
*/
public String kind();
}
package com.spring.dao.impl;
import com.spring.dao.Language;
import jdk.jfr.Label;
import javax.security.auth.callback.LanguageCallback;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 16:36:08
*/
public class HanYu implements Language {
@Override
public String kind() {
return "汉语";
}
}
package com.spring.dao.impl;
import com.spring.dao.Language;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 16:37:18
*/
public class English implements Language {
@Override
public String kind() {
return "英语";
}
}
package com.spring.dao;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:22:50
*/
public interface Human {
/**
* 吃
*/
void eat();
/**
* 睡
*/
void sleep();
/**
* 说话
*/
void speak();
}
package com.spring.dao.impl;
import com.spring.dao.Human;
import com.spring.dao.Language;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:24:00
*/
public class Chinese implements Human {
private Language language;
public Chinese() {
this.language = language;
}
/**
* 构造方法注入
* @param language
*/
public Chinese(Language language) {
this.language = language;
}
@Override
public void eat() {
System.out.println("中国人吃吃吃吃吃");
}
@Override
public void sleep() {
System.out.println("中国人睡睡睡睡睡");
}
@Override
public void speak() {
System.out.println("我是中国人,我说的是" + language.kind());
}
}
package com.spring.dao.impl;
import com.spring.dao.Human;
import com.spring.dao.Language;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:24:18
*/
public class American implements Human {
private Language language;
/**
* setter方法注入
* @param language
*/
public void setLanguage(Language language) {
this.language = language;
}
@Override
public void eat() {
System.out.println("美国人吃吃吃吃吃");
}
@Override
public void sleep() {
System.out.println("美国人睡睡睡睡睡");
}
@Override
public void speak() {
System.out.println("我是美国人,我说的是" + language.kind());
}
}
package com.spring.test;
import com.spring.dao.Human;
import javafx.application.Application;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Base64;
/**
* @author 一宿君(CSDN : qq_52596258)
* @date 2021-07-12 15:38:59
*/
public class Test3 {
public static void main(String[] args) {
/**
* 采用Spring的bean工厂方式创建实例
*/
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("src/applicationContext.xml"));
Human human1 = (Human) beanFactory.getBean("ch2");
human1.eat();
human1.sleep();
human1.speak();
Human human2 = (Human)beanFactory.getBean("am2");
human2.eat();
human2.sleep();
human2.speak();
/**
* 采用应用程序上下文方式创建bean实例
*/
//绝对路径(不推荐使用)
//ApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/applicationContext.xml");
//相对路径
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Human human3 = (Human) applicationContext.getBean("ch2");
human3.eat();
human3.sleep();
human3.speak();
Human human4 = (Human)applicationContext.getBean("am2");
human4.eat();
human4.sleep();
human4.speak();
}
}