java工厂模式详解,Spring框架----IOC的概念和作用之工厂模式

 2023-09-28 阅读 31 评论 0

摘要:创建bean对象的工厂 bean在计算机英语中,有可重用组件的含义 可重用:可反复使用。组件:组成部分,比如service可以被servlet反复使用,dao被service使用。service可以看成是可重用的组成部分。 javabean>=实体类,用Java语言编写的可重

创建bean对象的工厂

bean在计算机英语中,有可重用组件的含义
可重用:可反复使用。组件:组成部分,比如service可以被servlet反复使用,dao被service使用。service可以看成是可重用的组成部分。
javabean>=实体类,用Java语言编写的可重用组件
bean对象的工厂它就是创建service和dao对象的
如何创建:
第一个需要一个配置文件来配置我们的service和dao
配置的内容:全限定类名,唯一标识(key-value)(用于取到这个类)
第二个通过读取配置文件中配置的内容,反射创建对象
我的配置文件可以时xml也可以时properties,properties较为简单
bean.properties

accountService=com.yujie.service.Impl.AccountServiceImpl
accountDao=com.yujie.dao.dao.Impl.AccountDaoImpl
public class BeanFactory {//定义一个properties对象private static Properties props;//使用静态代码块为properties对象赋值static{try {//实例化对象props = new Properties();         //降低,而不是消除//获取properties文件的流对象,类加载器是动态获取文件的绝对路径InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");       //获取配置文件props.load(in);               //读取流}catch (Exception e){throw new ExceptionInInitializerError("初始化properties失败")}}//这里不能写死了某个类名//根据bean的名称获取bean对象,通过读取配置文件的方式完成反射public static Object getBean(String beanName){Object bean=null;try {String beanPath = props.getProperty(beanName);        //通过beanname来得到bean的路径bean = Class.forName(beanPath).newInstance();         //通过反射机制来获取对象}catch(Exception e){e.printStackTrace();}return bean;}}

java工厂模式详解、能不能解耦呢?下面改装一下,实现解耦

public class Client {public static void main(String[] args) {
//        IAccountService as=new AccountServiceImpl();IAccountService as=(IAccountService)BeanFactory.getBean("accountService");as.saveAccount();}
}
public class AccountServiceImpl implements IAccountService {
//    private IAccountDao accountDao=new AccountDaoImpl();private IAccountDao accountDao=(IAccountDao) BeanFactory.getBean("accountDao");public void saveAccount() {accountDao.saveAccount();}
}

这个就是工厂模式解耦,我们把accountDao给删掉,编译时没问题,运行时才报错在这里插入图片描述
这就是工厂模式解耦
但是这个代码仍然有问题,

for(int i=0;i<5;i++){IAccountService as=(IAccountService)BeanFactory.getBean("accountService");System.out.println(as);
}

Springboot框架、在这里插入图片描述
打印出来了5个对象,这时候对象是多例的,单例对象是说从始至终只有一个对象实例。他们有什么区别呢,
在serviceImpl中,i是一个类的成员,方法操作类成员的属性

private int i=1;
public void saveAccount() {accountDao.saveAccount();System.out.println(i);i++;
}

在这里插入图片描述
这时候i一直是1,不管有多少个service访问的时候,都是1。
如果是单例的话,此时每个编码都应该相同,比如5个都是com.yujie.service.Impl.AccountServiceImpl@74a14482
只被创建一次,从而类中的成员也就只会初始化一次。所以多个线程访问,多个对象访问时,由于对象的实例只有一个,类成员在方法能够进行改变的时候,单例就出现了。
多例对象对象被创建多次,其执行效率没有单例对象高
单例对象有线程问题,但是在我们service和dao中,没有类的方法对其类的属性进行调整,而是会把属性定义到方法中去,每次方法都会对他重新初始化,也能保证每次得到的都是1。
所以我们需要每次都是同一个对象,由于beanfactory创建对象的时候调用的时newInstance,每次都会调用默认构造函数创建对象。调整的前提是,我们的newInstance只能一次,如果创建了不存起来,Java的垃圾回收机制就会长时间不用时回收。所以在对象创建起来之后就要存起来
我们需要存储这些对象的,我们称之为容器

定义一个Map,用于存放我们要创建的对象,我们把它称之为容器

public class BeanFactory {//定义一个properties对象private static Properties props;//定义一个Map,用于存放我们要创建的对象,我们把它称之为容器private static Map<String,Object> beans;//使用静态代码块为properties对象赋值,静态代码块只在类加载的时候执行一次static{try {//实例化对象props = new Properties();         //降低,而不是消除//获取properties文件的流对象InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");       //获取配置文件props.load(in);               //读取流//用hashMap实例化容器beans=new HashMap<String, Object>();//取出配置文件中所有的keyEnumeration keys=props.keys();//遍历枚举while(keys.hasMoreElements()){//取出每个keyString key=keys.nextElement().toString();//根据key获取valueString beanPath=props.getProperty(key);//反射创建对象Object value=Class.forName(beanPath).newInstance();//把key和value存入容器中beans.put(key,value);}}catch (Exception e){throw new ExceptionInInitializerError("初始化properties失败");}}//根据bean的名称获取对象,这个对象时单例的public static Object getBean(String beanName){return beans.get(beanName);}
}

此时输出结果如上,当多个人在使用它访问时,此时就时单线程。第一个人再修改,后面的也跟着看到修改的结果,但是持久层和业务层不要定义可修改的类成员

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/101721.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息