小言_互联网的博客

【Spring】Spring对IoC的实现和依赖注入专题

346人阅读  评论(0)

1. 依赖注入:

1.1 set注入:

  • 基于set方法实现的, 底层会通过反射机制调用属性对应的set方法然后给属性赋值

  • 这种方式要求属性必须对外提供set方法

  • set注入的核心实现原理: 通过反射机制调用set方法来给属性赋值, 让俩个对象之间产生关系


   
  1. // xml
  2. <!-- 配置userDao -->
  3. <bean id= "userDaoBean" class= "com.powernode.bean.UserDao"/>
  4. <!-- 配置vipDao -->
  5. <bean id= "vipDaoBean" class= "com.powernode.bean.VipDao"/>
  6. <!-- 配置User -->
  7. <bean id= "userBean" class= "com.powernode.bean.User">
  8. <!-- 想让Spring调用对应的set方法, 需要配置property标签
  9. name属性怎么知道值: set方法的方法名, 去掉set, 然后把剩下的首字母小写
  10. ref翻译为引用, ref后面指定的是要注入的bean的id -->
  11. <property name= "userDao" ref= "userDaoBean"/>
  12. <property name= "vipDao" ref= "vipDaoBean"/>
  13. </bean>
  14. // User类
  15. public class User {
  16. private UserDao userDao;
  17. private VipDao vipDao;
  18. public void setVipDao (VipDao vipDao) {
  19. this.vipDao = vipDao;
  20. }
  21. // set注入, 必须提供一个set方法
  22. // Spring容器会调用这个set方法, 来给userDao属性赋值
  23. public void setUserDao (UserDao userDao) {
  24. this.userDao = userDao;
  25. }
  26. public void saveUser (){
  27. userDao.saveId();
  28. vipDao.save();
  29. }
  30. }
  31. // @Test
  32. public void setDI (){
  33. ApplicationContext ctx = new ClassPathXmlApplicationContext( "spring.xml");
  34. User userBean = ctx.getBean( "userBean", User.class);
  35. userBean.saveUser();
  36. }

1.2 构造注入:

  • 核心原理: 调用构造方法来给属性赋值

  • set注入是在对象构建好了之后调用set方法来完成赋值, 构造注入是在对象实例化的过程中赋值的


   
  1. // xml
  2. <bean id= "userDaoBean" class= "com.powernode.bean.UserDao"/>
  3. <bean id= "vipDaoBean" class= "com.powernode.bean.VipDao"/>
  4. <!-- 构造注入 3种方式 -->
  5. <bean id= "customerBean" class= "com.powernode.bean.Customer">
  6.     <!-- 指定构造方法的第一个参数, 下标是 0 -->
  7.     <constructor-arg index= "0" ref= "userDaoBean"/>
  8. <!-- 指定构造方法的第二个参数, 下标是 1 -->
  9. <constructor-arg index= "1" ref= "vipDaoBean"/>
  10. <!-- 根据构造方法参数的名字进行注入 -->
  11. <constructor-arg name= "userDao" ref= "userDaoBean"/>
  12. <constructor-arg name= "vipDao" ref= "vipDaoBean"/>
  13. <!-- 这种方式实际上是根据类型进行注入, Spring会自动根据类型来判断把ref注入给哪个参数-->
  14. <constructor-arg ref= "userDaoBean"/>
  15. <constructor-arg ref= "vipDaoBean"/>
  16. </bean>
  17. // Customer类
  18. public class Customer {
  19. private UserDao userDao;
  20. private VipDao vipDao;
  21. public Customer (UserDao userDao, VipDao vipDao) {
  22. this.userDao = userDao;
  23. this.vipDao = vipDao;
  24. }
  25. public void insert (){
  26. userDao.saveId();
  27. vipDao.save();
  28. }
  29. }
  30. // @Test
  31. public void constructorDI (){
  32. ApplicationContext ctx = new ClassPathXmlApplicationContext( "beans.xml");
  33. Customer customerBean = ctx.getBean( "customerBean", Customer.class);
  34. customerBean.insert();
  35. }

2. set注入专题:

2.1 注入外部Bean:


   
  1. // xml
  2. <bean id="orderDaoBean" class="com.powernode.bean.dao.OrderDao"/>
  3. <bean id="orderBean" class="com.powernode.bean.Order">
  4. // 使用ref属性来引入, 这就是注入外部bean
  5.     <property name="orderDao" ref="orderDaoBean"/>
  6. </bean>
  7. // Order类
  8. public class Order {
  9. private OrderDao orderDao;
  10. public void setOrderDao(OrderDao orderDao) {
  11. this.orderDao = orderDao;
  12. }
  13. public void generate(){
  14. orderDao.insert();
  15. }
  16. }

2.2 注入内部Bean:


   
  1. // xml
  2. <bean id="orderBean2" class="com.powernode.bean.Order">
  3. <property name="orderDao">
  4. <!-- 在property标签中使用嵌套的bean标签, 这就是内部bean -->
  5. <bean class="com.powernode.bean.dao.OrderDao"/>
  6. </property>
  7. </bean>
  8. // Order类
  9. public class Order {
  10. private OrderDao orderDao;
  11. public void setOrderDao(OrderDao orderDao) {
  12. this.orderDao = orderDao;
  13. }
  14. public void generate(){
  15. orderDao.insert();
  16. }
  17. }

2.3 注入简单类型:

简单类型有哪些:

  • 8 种基本类型和8种包装类型

  • 枚举

  • String字符串

  • 数字

  • 日期(java.util.Date), 在实际的开发中, 一般不会把Date当做简单类型, 一般采用ref给Date类型的属性赋值

  • 时间时区类型

  • URI

  • URL

  • 语言类


   
  1. // xml
  2. <bean id= "peopleBean" class= "com.powernode.bean.People">
  3. // 如果是给简单类型赋值, 就不能使用ref, 需要使用value
  4. <property name= "name" value= "二狗"/>
  5. <property name= "age" value= "16"/>
  6. <property name= "classId" value= "1"/>
  7. </bean>
  8. // People类
  9. public class People {
  10. private String name;
  11. private int age;
  12. private int classId;
  13. public void setName (String name) { this.name = name;}
  14. public void setAge (int age) { this.age = age;}
  15. public void setClassId (int classId) { this.classId = classId;}
  16. @Override
  17. public String toString () {
  18. return "People{" +
  19. "name='" + name + '\'' +
  20. ", age=" + age +
  21. ", classId=" + classId +
  22. '}';
  23. }
  24. }
  25. // @Test
  26. public void setDI3 (){
  27. ApplicationContext ctx = new ClassPathXmlApplicationContext( "set-DI.xml");
  28. People peopleBean = ctx.getBean( "peopleBean", People.class);
  29. System.out.println(peopleBean);
  30. }

2.4 注入数组:

  • 基本类型和非基本类型的数组注入, 如下:


   
  1. // xml
  2. <bean id= "friend1" class= "com.powernode.bean.Friend">
  3. <property name= "name" value= "小北"/>
  4. </bean>
  5. <bean id= "friend2" class= "com.powernode.bean.Friend">
  6. <property name= "name" value= "小爱"/>
  7. </bean>
  8. <bean id= "friend3" class= "com.powernode.bean.Friend">
  9. <property name= "name" value= "小花"/>
  10. </bean>
  11. <bean id= "stu" class= "com.powernode.bean.Student">
  12. // 这个数组当中的元素类型是String简单类型
  13. <property name= "stus">
  14. <array>
  15. <value> "张三"</value>
  16. <value> "李四"</value>
  17. <value> "王二蛋"</value>
  18. <value> "大锤"</value>
  19. </array>
  20. </property>
  21. // 这个数组当中的类型就不是简单类型
  22. <property name= "friends">
  23. <array>
  24. <ref bean= "friend1"/>
  25. <ref bean= "friend2"/>
  26. <ref bean= "friend3"/>
  27. </array>
  28. </property>
  29. </bean>
  30. // Student类
  31. public class Student {
  32. private String[] stus;
  33. private Friend[] friends;
  34. public void setStus (String[] stus) { this.stus = stus;}
  35. public void setFriends (Friend[] friends) { this.friends = friends;}
  36. @Override
  37. public String toString () {
  38. return "Student{" +
  39. "stus=" + Arrays.toString(stus) +
  40. ", friends=" + Arrays.toString(friends) +
  41. '}';
  42. }
  43. }
  44. // Friend类
  45. public class Friend {
  46. private String name;
  47. public void setName (String name) { this.name = name;}
  48. @Override
  49. public String toString () {
  50. return "Friend{" +
  51. "name='" + name + '\'' +
  52. '}';
  53. }
  54. }
  55. // @Test
  56. public void setDI5 (){
  57. ApplicationContext ctx = new ClassPathXmlApplicationContext( "set-DI.xml");
  58. Student stu = ctx.getBean( "stu", Student.class);
  59. System.out.println(stu);
  60. }

2.5 注入List集合和Set集合:

  • 简单类型


   
  1. // xml
  2. <bean id= "people" class= "com.powernode.bean.People">
  3. <property name= "names">
  4. <list> // list集合有序可重复
  5. <value>张三</value>
  6. <value>达尔</value>
  7. <value>溜达</value>
  8. <value>张三</value>
  9. <value>张三</value>
  10. </list>
  11. </property>
  12. <property name= "addrs">
  13. <set> // set集合无序不可重复
  14. <value>张二</value>
  15. <value>达</value>
  16. <value>溜达</value>
  17. </set>
  18. </property>
  19. </bean>
  20. // People类
  21. public class People {
  22. private List<String> names;
  23. private Set<String> addrs;
  24. public void setNames (List<String> names) { this.names = names;}
  25. public void setAddrs (Set<String> addrs) { this.addrs = addrs;}
  26. @Override
  27. public String toString () {
  28. return "People{" +
  29. ", names=" + names +
  30. ", addrs=" + addrs +
  31. '}';
  32. }
  33. }
  34. // @Test
  35. public void setDI5 (){
  36. ApplicationContext ctx = new ClassPathXmlApplicationContext( "set-DI.xml");
  37. People people = ctx.getBean( "people", People.class);
  38. System.out.println(people);
  39. }

2.6 注入Map集合和properties:

  • Properties本质上也是一个Map集合

  • Properties的父类HashTable, HashTable实现了Map接口

  • 虽然这个也是Map集合, 但是和Map的注入方式不完全一样

  • Properties的key和value只能是String类型


   
  1. // xml
  2. <bean id= "people" class= "com.powernode.bean.People">
  3. <property name= "phones"> // 注入map集合
  4. <map>
  5. <entry key-ref= "" value-ref= ""/> // 如果key和value不是简单类型就用这个
  6. <entry key= "1" value= ".."/>
  7. <entry key= "2" value= ".."/>
  8. <entry key= "3" value= ".."/>
  9. </map>
  10. </property>
  11. <property name= "properties"> // 注入properties属性类对象
  12. <props>
  13. <prop key= "..">...</prop>
  14. <prop key= "..">...</prop>
  15. <prop key= "..">...</prop>
  16. </props>
  17. </property>
  18. </bean>
  19. // People类
  20. public class People {
  21. private Map<Integer,String> phones;
  22. private Properties properties;
  23. public void setPhones (Map<Integer, String> phones) { this.phones = phones;}
  24. public void setProperties (Properties properties) { this.properties = properties;}
  25. @Override
  26. public String toString () {
  27. return "People{" +
  28. "phones=" + phones +
  29. ", properties=" + properties +
  30. '}';
  31. }
  32. }
  33. // @Test
  34. public void setDI5 (){
  35. ApplicationContext ctx = new ClassPathXmlApplicationContext( "set-DI.xml");
  36. People people = ctx.getBean( "people", People.class);
  37. System.out.println(people);
  38. }

2.7 注入null和空字符串:

  • 注入空字符串使用: <value/> 或者value=""


   
  1. // xml
  2. <bean id= "dog" class= "com.powernode.bean.Dog">
  3. // 注入空字符串的第一种方式
  4. <property name= "name">
  5. <value/>
  6.     </property>
  7. // 注入空字符串的第二种方式
  8. <property name= "age" value= ""/>
  9. </bean>
  10. // Dog类
  11. public class Dog {
  12. private String name;
  13. private int age;
  14. public void setName (String name) { this.name = name;}
  15. public void setAge (int age) { this.age = age;}
  16. @Override
  17. public String toString () {
  18. return "Dog{" +
  19. "name='" + name + '\'' +
  20. ", age=" + age +
  21. '}';
  22. }
  23. }
  24. // @Test
  25. public void setEmpty (){
  26. ApplicationContext ctx = new ClassPathXmlApplicationContext( "set-DI.xml");
  27. Dog dog = ctx.getBean( "dog", Dog.class);
  28. System.out.println(dog);
  29. }
  • 注入null使用: <null/> 或者不为该属性赋值


   
  1. // xml
  2. <bean id= "dog" class= "com.powernode.bean.Dog">
  3. // 不给属性注入, 属性的默认值就是null
  4. // <property name="name" value=""/>
  5. // 手动注入null
  6.     <property name= "age">
  7. < null/>
  8. </property>
  9. </bean>

2.8 注入特殊字符:


   
  1. // xml
  2. <bean id= "math" class= "com.powernode.bean.Dog">
  3. // 第一种方案
  4. <property name= "result" value= "2 < 3"/>
  5. // 第二种方案
  6. <property name= "result">
  7. // 只能使用value标签
  8. <value><![CDATA[ 2 < 3]]></value>
  9. </property>
  10. </bean>

3. 引入外部的属性配置文件:

引入外部的properties文件

  • 第一步: 引入context命名空间

  • 第二步: 使用标签context: property-placeholder的location属性来指定属性配置文件的路径

  • location默认从类的根路径下开始加载资源


   
  1. // xml
  2. <context: property-placeholder location="jdbc.properties"/>
  3. // 配置数据源
  4. <bean id="ds" class="com....jdbc.MyDataSource">
  5. // 怎么取值呢? ${key}
  6. <property name="driver" value="${jdbc.driverClass}"/>
  7. <property name="url" value="${jdbc.url}"/>
  8. <property name="username" value="${jdbc.username}"/>
  9. <property name="password" value="${jdbc.password}"/>
  10. </bean>
  11. // jdbc.properties
  12. jdbc.driverClass=com.mysql.cj.jdbc.Driver
  13. jdbc.url=jdbc:mysql://localhost:3306/spring6
  14. jdbc.username=root
  15. jdbc.password=123

转载:https://blog.csdn.net/qq_68993495/article/details/128906959
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场