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);}
}
此时输出结果如上,当多个人在使用它访问时,此时就时单线程。第一个人再修改,后面的也跟着看到修改的结果,但是持久层和业务层不要定义可修改的类成员。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态