首页 文章详情

Spring复习-IOC和DI

william1024 | 28 2024-05-24 19:20 0 0 0
UniSMS (合一短信)

    学习Spring后没有怎么使用,最近因为一些需求,考虑使用Spring可能更为合适,准备把一个flask项目重构掉,一边复习一边使用吧,今天做一次简单的复习、总结。文章来源是对msb视频课程的提取。

关于IOC的定义什么的不作表述,总括就是处理对象怎么创建的。

其核心思想我理解就是java利用反射来创建对象,帮助开发者更灵活的使用对象

先看一下普通的获取对象的步骤

创建一个接口

      
        package com.dola.dao;
      
      
        
          
public interface EmpDao { int addEmp(); }

ff7df3328ff1eb2dbff67818ef49b410.webp


然后创建这个接口的实现类

      
        package com.dola.dao.impl;
      
      
        
          
import com.dola.dao.EmpDao;
public class EmpDaoImpl implements EmpDao {
public int addEmp() { System.out.println("EmpDaoImpl addEmp invoked"); return 0; } }

79f62835eec883c2bc78e88cfc5e783c.webp

创建好后,来实例化个EmpDaoImpl对象

      
        package com.dola.test;
      
      
        
          
import com.dola.dao.EmpDao; import com.dola.dao.impl.EmpDaoImpl; import org.junit.Test;
public class Test1 { @Test public void testGetBean() { EmpDao empDao = new EmpDaoImpl(); empDao.addEmp(); }
}

65c480997d9d7c5020873ca522bd1f62.webp

运行一下,就可以看到输出了

e68edc242ce54384e5711acc7ee06873.webp

ok,这也就是平常来创建对象的简单概括了

那刚才在实现EmpDao的这个接口时候,需要进行一点变动,创建一个EmpDaoImpl2

      
        package com.dola.dao.impl;
      
      
        
          
import com.dola.dao.EmpDao;
public class EmpDaoImpl2 implements EmpDao {
public int addEmp() { System.out.println("EmpDaoImpl addEmp invoked2"); return 0; } }

怎来获取这个新的对象呢?

当然就得把代码中new的对象给切换一下

      
        package com.dola.test;
      
      
        
          
import com.dola.dao.EmpDao; import com.dola.dao.impl.EmpDaoImpl; import com.dola.dao.impl.EmpDaoImpl2; import org.junit.Test;
public class Test1 { @Test public void testGetBean() { EmpDao empDao = new EmpDaoImpl2(); empDao.addEmp(); }
}

这样看起来是没有问题,把new后面的换一下就好了,很轻松呀,没什么问题,可是,如果有多个文件或者多处这样new了一下又一下,去改的时候真的还是蛮复杂的。。。

来体验一下IOC创建对象的过程吧

刚才创建好EmpDao的接口和EmpDaoImpl的实现类了,现在使用Spring的配置文件来生成一个容器,或者说创建一个map集合,内容里面装上实例化一个EmpDaoImp的对象

      
        <?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">
      
      
        
          
<bean id="empDao" class="com.dola.dao.impl.EmpDaoImpl"></bean> </beans>

c0cdfef6f91a03f3abed531dc172bf56.webp


这个配置文件编辑好后,会生成一个map,键为empDao,键值为

com.dola.dao.impl.EmpDaoImpl

那么怎么不通过new的方式来获取这个对象呢,想一下,现在创建这个即容器了,对象就在这个容器里了,想获取对象不就是获取到这个容器,然后直接从容器里取不就好了么

      
        package com.dola.test;
      
      
        
          
import com.dola.dao.EmpDao; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
@Test public void testGetBean(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml"); EmpDao empDao = applicationContext.getBean("empDao",EmpDao.class); empDao.addEmp();
}
}

49013a0bdfb53df7cc4691611b9a4d49.webp

运行一下,自然也能正常得到结果

1acb7ed163d7f871b153d44f24c111a9.webp

再回到刚才那个问题里去,在使用IOC时候怎么来改变获取的对象呢?这个时候就太简单啦,只需要把这个容器指向的对象的路径给改一下就可以了

      
        <?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">
      
      
        
          
<bean id="empDao" class="com.dola.dao.impl.EmpDaoImpl2"></bean> </beans>


修改完之后,甚至都不需要重新编译,这个empDao指向的对象就都是EmpDaoImpl2的对象了,回味一下,真的是清爽很多。

简单说一下这个原理:

      
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
      
    

这行代码通过读取配置文件创建了一个容器,然后通过

      
        <bean id="empDao" class="com.dola.dao.impl.EmpDaoImpl2"></bean>
      
    

这行代码中的类的全路径通过反射创建了一个对象放进了容器(一个map集合),并且给他取了个名字叫empDao(键)

最后通过工厂模式的getBean方法获取到对象

哦对了,什么是Bean,就直接理解为对象吧(也就是对象)


对象的创建也就上面说的了,那对象创建好了,怎么赋值?那就是和IOC总是一块出现的DI了,关于DI,总括就是处理对象的属性赋值相互依赖关系

创建一个类

      
        package com.dola.bean;
      
      
        
          
//import netscape.security.UserDialogHelper;
public class User{ private Integer userid; private String username; private String password ;
public User() { System.out.println("无参构造方法"); }
public User(Integer userid, String username, String password) { System.out.println("全参构造方法"); this.userid = userid; this.username = username; this.password = password; }
public void setUserid(Integer userid) { this.userid = userid; }
public void setUsername(String username) { this.username = username; }
public void setPassword(String password) { this.password = password; }


public Integer getUserid() { return userid; }
public String getUsername() { return username; }
public String getPassword() { return password; }
@Override public String toString() { return "User{" + "userid=" + userid + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }

18b8cdd8b3e5be47c23da52f1ca028fc.webp


然后去编辑配置文件,来创建用来装被赋值的对象的那个容器

      
        <?xml version="1.0" encoding="UTF-8"?>
      
      
        <beans xmlns="http://www.springframework.org/schema/beans"
      
      
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      
      
               xmlns:p="http://www.springframework.org/schema/p"
      
      
               xmlns:c="http://www.springframework.org/schema/c"
      
      
               xsi:schemaLocation="http://www.springframework.org/schema/beans
      
      
               http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      
        
          

<bean id="user1" class="com.dola.bean.User" lazy-init="true" scope="singleton"></bean> <!-- lazy-init默认为false 这个时候只要对象被创建就会调用对象的无参构造方法 为true时候,创建时候调用对象的无参构造方法,对象被调用时候才执行对象的无参构造方法 --> <!-- scope 控制全文在获取对象时候是不是总使用同一个对象 默认是使用同一个对象 -->
<bean id="user2" class="com.dola.bean.User"> <!-- property标签的使用其实就是调用对象的set方法,所以使用这个的前提就是得有set方法 --> <property name="userid" value="1"></property> <property name="username" value="test1"></property> <property name="password" value="test1"></property> </bean>
<bean id="user3" class="com.dola.bean.User"> <!-- constructor-arg标签的使用其实就是调用对象的有全参构造方法 --> <constructor-arg name="userid" value="2"></constructor-arg> <constructor-arg name="username" value="test2"></constructor-arg> <constructor-arg name="password" value="test2"></constructor-arg> </bean>
<!-- 可以对上面两种赋值操作进行简化,也就是p命名空间和c命名空间,使用前需要在最上面添加两条约束--> <!-- xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" --> <bean id="user4" class="com.dola.bean.User" p:userid="4" p:username="test4" p:password="test4"></bean> <bean id="user5" class="com.dola.bean.User" c:userid="5" c:username="test5" c:password="test5"></bean>

</beans>

82463566156c9465af1c52c4f154f4ff.webp

有了这么些个对象,使用一下看看吧

      
        package com.dola.test;
      
      
        
          
import com.dola.bean.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
@Test public void testGetBean(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml"); User user1 = applicationContext.getBean("user1",User.class);

User user2 = applicationContext.getBean("user2",User.class); System.out.println(user2);
User user3 = applicationContext.getBean("user3",User.class); System.out.println(user3);
User user4 = applicationContext.getBean("user4",User.class); System.out.println(user4);
User user5 = applicationContext.getBean("user5",User.class); System.out.println(user5);
}
}

2d361637c36bbb3eda1e0431273548a2.webp



再看一下对象的引入

创建一个Mouse类

      
        package com.dola.bean;
      
      
        
          
import java.util.Date;
public class Mouse { private String name; private Date birthday;
public Mouse() { }
public Mouse(String name, Date birthday) { this.name = name; this.birthday = birthday; }
public void setName(String name) { this.name = name; }
public void setBirthday(Date birthday) { this.birthday = birthday; }
public String getName() { return name; }
public Date getBirthday() { return birthday; }
@Override public String toString() { return "Mouse{" + "name='" + name + '\'' + ", birthday=" + birthday + '}'; } }

aa6b56b340311d963f600770c92133ae.webp

然后去编辑配置文件来创建对象(Data 不是一个基本数据类型,使用的时候需实例化一个对象才能使用)

      
        <?xml version="1.0" encoding="UTF-8"?>
      
      
        <beans xmlns="http://www.springframework.org/schema/beans"
      
      
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      
      
               xmlns:p="http://www.springframework.org/schema/p"
      
      
               xmlns:c="http://www.springframework.org/schema/c"
      
      
               xsi:schemaLocation="http://www.springframework.org/schema/beans
      
      
               http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      
        
          

<bean id="date1" class="java.util.Date"></bean>
<bean id="mouse1" class="com.dola.bean.Mouse"> <property name="name" value="Jerry1"></property> <property name="birthday" ref="date1"></property> </bean> </beans>

5a77a09adcc8d633cec3c51b0ee7d9b6.webp

很明显,这个跟刚才的差异就是引用对象时候,value变成了ref,紧接着,来获取这个容器里的对象看看

      
        package com.dola.test;
      
      
        
          
import com.dola.bean.Mouse; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test2 {
@Test public void testGetBean(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application2.xml"); Mouse mouse1 = applicationContext.getBean("mouse1",Mouse.class); System.out.println(mouse1); }
}

f9983537d899876304824c922b3b9508.webp

什么?不过瘾?那搞一只猫吧,让猫拿住这个老鼠(建立对象之间的依赖关系)

      
        package com.dola.bean;
      
      
        
          
public class Cat { private String name; private Mouse mouse;
public Cat() { }
public Cat(String name, Mouse mouse) { this.name = name; this.mouse = mouse; }
public void setName(String name) { this.name = name; }
public void setMouse(Mouse mouse) { this.mouse = mouse; }
public String getName() { return name; }
public Mouse getMouse() { return mouse; }
@Override public String toString() { return "Cat{" + "name='" + name + '\'' + ", mouse=" + mouse + '}'; } }

63e7aa25817746d5dc24045f9e37e0aa.webp

修改配置文件

      
        <?xml version="1.0" encoding="UTF-8"?>
      
      
        <beans xmlns="http://www.springframework.org/schema/beans"
      
      
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      
      
               xmlns:p="http://www.springframework.org/schema/p"
      
      
               xmlns:c="http://www.springframework.org/schema/c"
      
      
               xsi:schemaLocation="http://www.springframework.org/schema/beans
      
      
               http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      
        
          

<bean id="date1" class="java.util.Date"></bean>
<bean id="mouse1" class="com.dola.bean.Mouse"> <property name="name" value="Jerry1"></property> <property name="birthday" ref="date1"></property> </bean>
<bean id="cat1" class="com.dola.bean.Cat"> <property name="name" value="Tom"></property> <property name="mouse" ref="mouse1"></property> </bean> </beans>

然后再修改获取容器的代码

      
        package com.dola.test;
      
      
        
          
import com.dola.bean.Mouse; import com.dola.bean.Cat; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test2 {
@Test public void testGetBean(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application2.xml");
Mouse mouse1 = applicationContext.getBean("mouse1",Mouse.class); System.out.println(mouse1);
Cat cat = applicationContext.getBean("cat1",Cat.class); System.out.println(cat); }
}

d2d2e5a651606583c7c3136c3d247682.webp

完成,这样搞下来是不是还蛮好理解的


(不能拖延,4月29夜里写的,想着看还需要改不,结果一直没动,然后就发了

fbc9f0910f68f3c0f028a13866db2db7.webp


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter