Spring依赖注入

新建PersonIDao 和PersonDao底实现Save方法:

  1. public interface PersonIDao {
  2. public void save();
  3. }
  1. public class PersonDaoImpl implements PersonIDao{
  2. @Override
  3. public void save() {
  4. System.out.println("我是dao的Save方法");
  5. }
  6. }

在Bean.xml中注入PersonIDao,并将PersonIDao注入到PersonService中:

  1. <bean id="personIDao" class="cn.dao.impl.PersonDaoImpl" />
  2. <bean id="personIService" class="cn.server.impl.PersonServiceImpl">
  3. <property name="personIDao" ref="personIDao" />
  4. </bean>

在PersonService中添加PersonIDao类型属性并实现属性的set方法,然后调用PersonIDao的save方法

  1. public class PersonServiceImpl implements PersonIService {
  2. private PersonIDao personIDao;
  3.  
  4. public PersonIDao getPersonIDao() {
  5. return personIDao;
  6. }
  7. public void setPersonIDao(PersonIDao personIDao) {
  8. this.personIDao = personIDao;
  9. }
  10. @Override
  11. public void save() {
  12. personIDao.save();
  13. }
  14. }

然后测试:

  1. @Test
  2. public void testSave() {
  3. AbstractApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
  4. PersonIService personIService=(PersonIService)ac.getBean("personIService");
  5. personIService.save();
  6. }

编码剖析Spring依赖注入的原理

通过编码的方法式来剖析Spring 依赖注入的原理方法,新建PropertyDefinition类用来承载Bean中注入的property的属性:

  1. public class PropertyDefinition {
  2. private String name;
  3. private String ref;
  4. public PropertyDefinition(){}
  5. public PropertyDefinition(String name, String ref) {
  6. super();
  7. this.name = name;
  8. this.ref = ref;
  9. }
  10.  
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public String getRef() {
  18. return ref;
  19. }
  20. public void setRef(String ref) {
  21. this.ref = ref;
  22. }
  23. }

新建BeanDefinition用来承载解析到的Bean属性

  1. public class BeanDefinition {
  2. private String id;
  3. private String className;
  4. private List<PropertyDefinition> properties=new ArrayList<PropertyDefinition>();
  5. public BeanDefinition(){}
  6. public BeanDefinition(String id, String className) {
  7. this.id = id;
  8. this.className = className;
  9. }
  10. public String getId() {
  11. return id;
  12. }
  13. public void setId(String id) {
  14. this.id = id;
  15. }
  16. public String getClassName() {
  17. return className;
  18. }
  19. public void setClassName(String className) {
  20. this.className = className;
  21. }
  22. public List<PropertyDefinition> getProperties() {
  23. return properties;
  24. }
  25. public void setProperties(List<PropertyDefinition> properties) {
  26. this.properties = properties;
  27. }
  28. }

新建OtherClassPathXMLApplicationContext 用来解析bean.xml

  1. public class OtherClassPathXMLApplicationContext {
  2. private List<BeanDefinition> list=new ArrayList<BeanDefinition>();
  3. private Map<String,Object> beans=new HashMap<String, Object>();
  4.  
  5. public OtherClassPathXMLApplicationContext(String fileName){
  6. this.readXML(fileName);
  7. this.instanceBeans();
  8. this.instanceProperties();
  9. }
  10. private void instanceBeans(){
  11. for(BeanDefinition bean : list){
  12. try {
  13. // 创建Bean实例,并放到Map中
  14. if(bean.getClassName()!=null && !bean.getClassName().trim().equals("")){
  15. beans.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
  16. }
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. private void instanceProperties(){
  23. for(BeanDefinition beanDefinition : list){
  24. Object bean=beans.get(beanDefinition.getId());
  25. if(bean!=null){
  26. try {
  27. // 获取bean下所有的属性定义描述
  28. PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
  29. for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
  30. for(PropertyDescriptor propertyDescriptor : ps){
  31. // 如果bean下的属性名字与当前的BeanDefinition下的属性名称一样的话,则将引用对象注入到属性
  32. if(propertyDefinition.getName().equals(propertyDescriptor.getName())){
  33. Method setter=propertyDescriptor.getWriteMethod(); // 获取Bean的所有写入的方法 即 setter方法
  34. setter.setAccessible(true); // true: 直接访问私有属性,将例子中的私有属性改值。
  35. Object value=beans.get(propertyDefinition.getRef());
  36. setter.invoke(bean, value); // 把引用对象注入属性
  37. break;
  38. }
  39. }
  40. }
  41. } catch (Exception e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }
  46. }
  47. private void readXML(String fileName){
  48. SAXReader saxReader = new SAXReader();
  49. Document doc=null;
  50. try{
  51. // JAVA里面对于类进行调用配置资源的文件数据,以this.getClass().getResourceAsStream()来读取比较合适。
  52. // 路径采用相对路径直接可以从工程的path路径去找。
  53. URL xmlpath=this.getClass().getClassLoader().getResource(fileName);
  54. doc=saxReader.read(xmlpath);
  55. Map<String,String> nsMap=new HashMap<String,String>();
  56. nsMap.put("ns", "http://www.springframework.org/schema/beans"); // 加入命名空间
  57. XPath xsub=doc.createXPath("//ns:beans/ns:bean"); // 创建 beans/bean的查询路径
  58. xsub.setNamespaceURIs(nsMap); // 设置命名空间
  59. List beans=xsub.selectNodes(doc); // 获取文档下的所有bean节点
  60. for(Object node : beans){
  61. Element element=(Element)node;
  62. String id=element.attributeValue("id");
  63. String className=element.attributeValue("class");
  64. BeanDefinition bean=new BeanDefinition(id,className);
  65.  
  66. // 编码剖析Spring依赖注入的原理
  67. // 加载bean下的Property
  68. XPath xproperty=element.createXPath("ns:property"); // 为xproperty 添加查询路径
  69. xproperty.setNamespaceURIs(nsMap);
  70. List properties=xproperty.selectNodes(element); // 查询出bean下的所有property
  71. for(Object propertyNode : properties){
  72. Element propertyElement=(Element)propertyNode;
  73. String name=propertyElement.attributeValue("name");
  74. String ref=propertyElement.attributeValue("ref");
  75. bean.getProperties().add(new PropertyDefinition(name, ref));
  76. }
  77. list.add(bean);
  78. }
  79.  
  80. }catch(Exception e){
  81. e.printStackTrace();
  82. }
  83. }
  84. // 通过Id名称,获取Bean
  85. public Object getBean(String name){
  86. return beans.get(name);
  87. }
  88. }

测试代码:

  1. @Test
  2. public void testSave2() {
  3. OtherClassPathXMLApplicationContext ac = new OtherClassPathXMLApplicationContext("beans.xml");
  4. PersonIService personIService=(PersonIService)ac.getBean("personIService");
  5. personIService.save();
  6. }

Spring、Spring依赖注入与编码剖析Spring依赖注入的原理的更多相关文章

  1. (转)编码剖析Spring依赖注入的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...

  2. (转)编码剖析Spring装配基本属性的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52856465 上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须 ...

  3. (转)编码剖析Spring管理Bean的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52832434 在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进 ...

  4. (转)编码剖析@Resource注解的实现原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52860046 上文我们已经学会使用@Resource注解注入属性.学是学会了,但也仅限于会使用 ...

  5. Spring、编码剖析Spring管理Bean的原理

    引入dom4j jar包 1.新建Person接口和PersonBean public interface PersonIService { public void helloSpring(); } ...

  6. Spring(八)编码剖析@Resource注解的实现原理

    配置文件beans2.xml <?xml version="1.0" encoding="UTF-8"? > <beans xmlns=&qu ...

  7. Spring第三弹—–编码剖析Spring管理Bean的原理

    先附一下编写的Spring容器的执行结果: 代码如下: 模拟的Spring容器类:   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  8. 编码剖析Spring管理bean的原理

    project目录 MyClassPathXMLApplicationContext读取xml,以及实例化bean. 因为是一开始实例化配置文件所有bean,所以需要构造器完成这些工作. packag ...

  9. Spring2.5学习3.2_编码剖析@Resource注解的实现原理

    首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在 ...

随机推荐

  1. racle undo 解析

    racle undo 解析 声明一下:关于oracle的文章基于boobooke小布老师视频,在我学习的过程中,每有体会拿来分享,虽然从理解到整理分享很耗时,但我想这样的学习是扎实的. Undo是干嘛 ...

  2. C++ new和delete实现原理——new和delete最终调用malloc和free

    new和delete最终调用malloc和free,关于malloc和free实现原理参见这篇文章: http://blog.csdn.net/passion_wu128/article/detail ...

  3. 设置edittext的hint位置

    <EditText android:id="@+id/edt_content" android:layout_width="fill_parent" an ...

  4. Android常用代码

    1.图片旋转 Bitmap bitmapOrg = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable. ...

  5. HBase 1、HBase介绍和工作原理

    HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利用了Google文件 ...

  6. Number Sequence(kmp)

        Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. A Game with Colored Balls

    题目链接 题意: 给一个长度为n的字符串,每次删除字母同样切连续的串,假设有多个,删除最左边的.最长的串.每次删除输出串的字母,每一个字母的下标(1-n) N (1 ≤ N ≤ 106),串仅仅包含r ...

  8. javascript模式——Mixin

    Mixin是一种扩展收集功能的方式,能提高代码的复用率. 在javascript中,原型可以继承于其它对象的原型,并且可以为任意数量的实例定义属性.可以利用这一点来促进函数的复用. 下面一段代码就是将 ...

  9. javascript设计模式——Singleton

    单例模式指的是只能被实例化一次. 推荐阅读: http://blog.mgechev.com/2014/04/16/singleton-in-javascript/ 比较通用的一种Singleton模 ...

  10. HTML——CSS样式表&布局页面

    CSS样式表: 一.作用:美化网页,页面布局. 二.分类: 内联,写在body里标签style=""里面的样式,优点是控制精确,可重用性差. 内嵌,嵌在网页的head里面,可重用性 ...