多平台统一管理软件接口,如何实现多平台统一管理软件接口
228
2023-03-21
Spring的Ioc模拟实现详细介绍
简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供;Spring里面就是IOC容器。
例如:
在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下
public Class ServiceImpl{
@Autowired
Dao dao;
public void getData(){
dao.getData();
}
在这里未初始化Dao直接使用是会报出空指针异常的,那么在Spring里面的做法就是通过反射来将需要的类帮你加载进来。
关于IOC:我们讲个故事吧!
有一个厨师,他在做一道菜的时候需要某种调味料(bean),可是他正好没有那瓶调味料(bean),这个时候他就必须去制作一瓶调味料(bean)出来。(这就像我们平时需要对象的时候一样:UserDao userdao=new UserDaoImpl)这个时候厨师的工作就不得不跟制作调味料联系起来,这就是所谓的“耦合”。(耦合程度高通说来说就是,我没了你我活不了了。);
这个时候IOC里的控制反转出来了,它提出,开辟一个仓库(容器),里面放着各种各样的调味料(bean),当你需要某种调味料(bean)的时候只要给出调味料的名字(beanName)就可以直接去拿取,代码类似这样:(UserDao user=仓库.get("调味料名字"));这样你就可以直接拿到了调味料 (bean)而不用等到你没有的时候再去制作一瓶出来。这就是所谓的将控制权转移出来,它将生产调味料(bean)的工作直接让仓库(容器)来制作(生产);
接下来依赖注入出来了,它就更加地强大的了,它提出厨师只要有一个瓶子(private UserDao userdao),并且将瓶子盖打开(方法:setUserDao( UserDao userdao){this.userdao=userdao}即提供对于的set方法 )再给瓶子贴上一个标签注明要放什么材料(在xml文件中配置一下 总结一下我的总结:IOC的主要目的就是实现解耦!解耦!解耦!重要的事情说三遍.由厨师的列子来说就是.我是一个厨师我只做菜,我不做调味料~~我不是一个做调味料的,我不跟制作调味料有那么大的关系. IOC的出现,厨师只要安心做好自己的事情(做菜),需要调味料直接去仓库拿取就行了!那么这样厨师跟调味料的制作之间的关系就分离开来了,这就是解耦!解耦!解耦!使两个东西的关系没那么紧密. 模拟IOC的实现,主要使用的技术是java的反射机制(模拟使用的是架构分为dao层,service层,controller层): 注:欢迎各位大佬的指点,小弟也在学习,说得不好多多包涵~ 一.编写dao类,用于测试: public interface IocDao { public void sayhello(); //一个用来测试的接口 } 二.编写dao的实现类: public class IocDaoImpl implements IocDao { @Override public void sayhello() { // TODO Auto-generated method stub System.out.println("hello word");//实现我们的dao接口里的方法 } } 三.编写service类: public interface IocDaoService { public void sayhello();//业务类接口,这里就跟dao一样 } 四.编写service的实现类: public class IocDaoServiceImpl implements IocDaoService { private IocDao iocDao; //创建一个接口. public IocDao getIocDao() { return iocDao; } //编写IocDao接口对应的set方法用于依赖注入 //依赖注入的方式有三种:接口注入,构造方法注入,set注入; //此处为set注入 public void setIocDao(IocDao iocDao) { this.iocDao = iocDao; } @Override public void sayhello() { // TODO Auto-generated method stub iocDao.sayhello();//调用接口方法 } } 五.编写bean.xml配置文件.(这里的i你可以看成是IocDaoImpl类,iocService看成IocDaoServiceImpl,iocDao这是IocDaoServiceImpl里的一个属性,这个属性传入的参数值为“i”); 六.编写工厂接口. //模拟ClassPathXmlApplicationContext实现的一个接口BeanFactory public interface BeanFactory { public Object getBean(String beanName); } 七.编写ClassPathXmlApplicationContext去读取配置文件,并且根据bean.xml里的配置对象去生成各种bean,完成其中的注入工作.(最重要的部分Ioc的实现原理),一字一句都有注释 //模拟ClassPathXmlApplicationContext去读取配置文件 public class ClassPathXmlApplicationContext implements BeanFactory { //定义map集合来存放bean.xml里的bean的id跟其对应的实例化对象 // //那么类似的存放bean.put("i",new IocDaoImpl());这样子. Map public ClassPathXmlApplicationContext(String xmlPath){ try { //创建SAXBuilder对象解析文档 SAXBuilder saxBuilder = new SAXBuilder(); //解析build里的参数是一个文件路径. Document document = saxBuilder.build(xmlPath); //document.getRootElement().getChildren("bean")获取所有 List elements = document.getRootElement().getChildren("bean"); //遍历 for (int i = 0; i < elements.size(); i++) { //获取第一个 Element element = (Element) elements.get(i); //获取 // //即String beanName="i"; String beanName = element.getAttributeValue("id"); //同上String clazz="com.hck.dao.impl.IocDaoImpl"; String clazz = element.getAttributeValue("class"); //加载类对象并且实例化.Object object=new IocDaoImpl(); Object object = Class.forName(clazz).newInstance();//object是IocDaoServiceImpl //将他们添加在map集合里,后面可以根据beanName直接获取到实例化对象. beans.put(beanName, object); //遍历 //第一个标签没有字标签所以直接跳过.已第二个为例子 // // List elements2 = element.getChildren("property"); for (int j = 0; j < elements2.size(); j++) { //此处我们将获得 Element element2 = (Element) elements2.get(j); //相当于String propertyName="iocDao"; String propertyName = element2.getAttributeValue("name"); //相当于String refBean="i"; String refBean = element2.getAttributeValue("ref"); //相当于String propertyName="IocDao"; //目的是为了得到一个方法的名字setIocDao,用于反射调用 propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); //这里的methodName="setIocDao"; String methodName = "set" + propertyName; //获取Map集合里Key="i"的值;i对应的是IocDaoImpl的实例化对象 //相当于 Object object2 =IocDaoImpl; Object object2 = beans.get(refBean); //获取IocDaoServiceImpl方法里的setIocDao方法. //第一个方法是方法名,第二个参数是方法的参数类型. Method method = object.getClass().getDeclaredMethod(methodName, object2.getClass().getInterfaces()); //调用方法,并传入参数,完成依赖注入. method.invoke(object, object2); } } // String beanName=document.getElementById(id).attributes().get("class"); // Object object=Class.forName(beanName).newInstance(); // return object; } catch (Exception e) { e.printStackTrace(); // TODO: handle exception http:// } } /* (non-Javadoc) * @see com.hck.ioc.BeanFactory#getBean() */ @Override public Object getBean(String beanName) { // TODO Auto-generated method stub return beans.get(beanName); } } 八.编写测试类 public class Ioc { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("src/bean.xml"); IocDaoService ids=(IocDaoService)applicationContext.getBean("iocService"); ids.sayhello(); } } 九.显示结果: hello word 总结 以上就是本文关于Spring的Ioc模拟实现详细介绍的全部内容,希望对大家有所帮助。欢迎参阅:spring的IoC和DI详解、spring配置扫描多个包问题解析、SpringJDBC批量处理数据代码示例等,有什么问题可以随时留言,欢迎大家交流讨论。
总结一下我的总结:IOC的主要目的就是实现解耦!解耦!解耦!重要的事情说三遍.由厨师的列子来说就是.我是一个厨师我只做菜,我不做调味料~~我不是一个做调味料的,我不跟制作调味料有那么大的关系. IOC的出现,厨师只要安心做好自己的事情(做菜),需要调味料直接去仓库拿取就行了!那么这样厨师跟调味料的制作之间的关系就分离开来了,这就是解耦!解耦!解耦!使两个东西的关系没那么紧密.
模拟IOC的实现,主要使用的技术是java的反射机制(模拟使用的是架构分为dao层,service层,controller层):
注:欢迎各位大佬的指点,小弟也在学习,说得不好多多包涵~
一.编写dao类,用于测试:
public interface IocDao {
public void sayhello(); //一个用来测试的接口
}
二.编写dao的实现类:
public class IocDaoImpl implements IocDao {
@Override
public void sayhello() {
// TODO Auto-generated method stub
System.out.println("hello word");//实现我们的dao接口里的方法
}
}
三.编写service类:
public interface IocDaoService {
public void sayhello();//业务类接口,这里就跟dao一样
}
四.编写service的实现类:
public class IocDaoServiceImpl implements IocDaoService {
private IocDao iocDao; //创建一个接口.
public IocDao getIocDao() {
return iocDao;
}
//编写IocDao接口对应的set方法用于依赖注入
//依赖注入的方式有三种:接口注入,构造方法注入,set注入;
//此处为set注入
public void setIocDao(IocDao iocDao) {
this.iocDao = iocDao;
}
@Override
public void sayhello() {
// TODO Auto-generated method stub
iocDao.sayhello();//调用接口方法
}
}
五.编写bean.xml配置文件.(这里的i你可以看成是IocDaoImpl类,iocService看成IocDaoServiceImpl,iocDao这是IocDaoServiceImpl里的一个属性,这个属性传入的参数值为“i”);
六.编写工厂接口.
//模拟ClassPathXmlApplicationContext实现的一个接口BeanFactory
public interface BeanFactory {
public Object getBean(String beanName);
}
七.编写ClassPathXmlApplicationContext去读取配置文件,并且根据bean.xml里的配置对象去生成各种bean,完成其中的注入工作.(最重要的部分Ioc的实现原理),一字一句都有注释
//模拟ClassPathXmlApplicationContext去读取配置文件
public class ClassPathXmlApplicationContext implements BeanFactory {
//定义map集合来存放bean.xml里的bean的id跟其对应的实例化对象
//
//那么类似的存放bean.put("i",new IocDaoImpl());这样子.
Map
public ClassPathXmlApplicationContext(String xmlPath){
try {
//创建SAXBuilder对象解析文档
SAXBuilder saxBuilder = new SAXBuilder();
//解析build里的参数是一个文件路径.
Document document = saxBuilder.build(xmlPath);
//document.getRootElement().getChildren("bean")获取所有
List elements = document.getRootElement().getChildren("bean");
//遍历
for (int i = 0; i < elements.size(); i++) {
//获取第一个
Element element = (Element) elements.get(i);
//获取
//
//即String beanName="i";
String beanName = element.getAttributeValue("id");
//同上String clazz="com.hck.dao.impl.IocDaoImpl";
String clazz = element.getAttributeValue("class");
//加载类对象并且实例化.Object object=new IocDaoImpl();
Object object = Class.forName(clazz).newInstance();//object是IocDaoServiceImpl
//将他们添加在map集合里,后面可以根据beanName直接获取到实例化对象.
beans.put(beanName, object);
//遍历
//第一个标签没有字标签所以直接跳过.已第二个为例子
//
//
List elements2 = element.getChildren("property");
for (int j = 0; j < elements2.size(); j++) {
//此处我们将获得
Element element2 = (Element) elements2.get(j);
//相当于String propertyName="iocDao";
String propertyName = element2.getAttributeValue("name");
//相当于String refBean="i";
String refBean = element2.getAttributeValue("ref");
//相当于String propertyName="IocDao";
//目的是为了得到一个方法的名字setIocDao,用于反射调用
propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
//这里的methodName="setIocDao";
String methodName = "set" + propertyName;
//获取Map集合里Key="i"的值;i对应的是IocDaoImpl的实例化对象
//相当于 Object object2 =IocDaoImpl;
Object object2 = beans.get(refBean);
//获取IocDaoServiceImpl方法里的setIocDao方法.
//第一个方法是方法名,第二个参数是方法的参数类型.
Method method = object.getClass().getDeclaredMethod(methodName,
object2.getClass().getInterfaces());
//调用方法,并传入参数,完成依赖注入.
method.invoke(object, object2);
}
}
// String beanName=document.getElementById(id).attributes().get("class");
// Object object=Class.forName(beanName).newInstance();
// return object;
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
http:// }
}
/* (non-Javadoc)
* @see com.hck.ioc.BeanFactory#getBean()
*/
@Override
public Object getBean(String beanName) {
// TODO Auto-generated method stub
return beans.get(beanName);
}
}
八.编写测试类
public class Ioc {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("src/bean.xml");
IocDaoService ids=(IocDaoService)applicationContext.getBean("iocService");
ids.sayhello();
}
}
九.显示结果:
hello word
总结
以上就是本文关于Spring的Ioc模拟实现详细介绍的全部内容,希望对大家有所帮助。欢迎参阅:spring的IoC和DI详解、spring配置扫描多个包问题解析、SpringJDBC批量处理数据代码示例等,有什么问题可以随时留言,欢迎大家交流讨论。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~