• Spring框架-IOC


    目录

    IOC概念和原理

    ​编辑 Spring提供IOC容器实现的两种方式(两个接口)

    IOC操作Bean管理

    1.什么是Bean管理

    2.IOC基于xml操作Bean管理

    1、基于xml方式创建对象

     2、基于xml方式注入属性-使用set方法进行注入

    3.基于xml方式注入属性-使用有参数构造

    4、IOC操作Bean管理xml注入其他类型属性

    4.基于xml方式注入属性-外部注入bean方式注入属性

    5.基于xml方式注入属性-内部bean和级联赋值注入属性的方法

    6.xml注入集合属性

    7.工厂bean-FactoryBean 

     8.bean创建单例和多利

    8.、bean生命周期

    9.Bean的后置处理器 

    10.xml自动装配

    11.     IOC操作Bean管理(外部属性文件-数据库)

     基于注解方式操作bean管理

         1、什么是注解

        2.Spring针对Bean管理中创建对象提供注解

    ​编辑3、基于注解方式实现对象创建

    4、基于注解方式实现属性注入

    5、基于注解方式实现属性注入

    完全注解开发(了解SpringBoot会真正涉及)



    Spring框架概述

    1.Spring是轻量级的开源的JavaEE框架

    2.Spring可以解决企业应用开发的复杂性

    3.Spring有两个核心部分

            IOC:控制反转,把创建对象过程交给Spring进行管理

            Aop:面向切片,不修改源代码进行功能增强

    4.Spring特点

            方便解耦,简化开发

            Aop编程支持

            方便程序测试

            方便和替他框架进行整合

            方便进行实务操作

            降低API开发难度

    5.使用到的jar包

    IOC概念和原理

    1.什么是IOC

    • 控制反转,把对象创建和对象之间的调用过程,交给Spring管理

               在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。为了方便理解和描述,我们可以将前者称为“调用者”,将后者称为“被调用者”。也就是说,调用者掌握着被调用者对象创建的控制权。

    但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里的,其大致步骤如下。

    1. 开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 标签、在 Java 类上使用 @Component 注解等。
    2. Spring 启动时,IoC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IoC 容器创建并管理的对象被称为 Spring Bean。
    3. 当我们想要使用某个 Bean 时,可以直接从 IoC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法),而不需要手动通过代码(例如 new Obejct() 的方式)创建。


    IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IoC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IoC 容器创建它所需要的对象(Bean)。

    这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IoC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。

    • 使用IOC目的:解耦合

    2.IoC 的工作原理

    在 Java 软件开发过程中,系统中的各个对象之间、各个模块之间、软件系统和硬件系统之间,或多或少都存在一定的耦合关系。

    若一个系统的耦合度过高,那么就会造成难以维护的问题,但完全没有耦合的代码几乎无法完成任何工作,这是由于几乎所有的功能都需要代码之间相互协作、相互依赖才能完成。因此我们在程序设计时,所秉承的思想一般都是在不影响系统功能的前提下,最大限度的降低耦合度。

    IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。

    1. 在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;
    2. 我们可以把 IoC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;
    3. 容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;
    4. IoC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean),并根据依赖关系将这个对象注入到依赖它的对象中。


    由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的,并没有在代码中紧密耦合,因此即使对象发生改变,我们也只需要在配置文件中进行修改即可,而无须对 Java 代码进行修改,这就是 Spring IoC 实现解耦的原理。

    3.结合例子理解IOC的解耦合

            需求:创建一个类的对象并调用它的方法

            原始方法:可以实现,但是耦合度太高了(两个类之间的联系太密切当其中一个类的信息改变,另一个类创建的对象也要跟着改变)

             工厂模式:解耦合,通过工厂模式降低了与UserDao的耦合度

            但并不能降到最低限度。所以引入IOC,可以将耦合度降到最低

    IOC过程:IOC思想是基于IOC容器完成的,IOC的容器底层就是对象工厂

     Spring提供IOC容器实现的两种方式(两个接口)

            1.BeanFactory:IOC容器基本实现,是Spring内部使用的接口,不提供给开发人员使用,获取对象时创见对象

            2.ApplicationContext:BeanFactory的子接口,提供更多更强大的的功能,一般由开发人员进行使用,加载配置文件时就会把配置文件对象进行创建。

            3.ApplicationContext有两个实现类

                    ClassPathXmlApplicationContext:是src路径下的文件直接传文件名和后缀即可,加载类路径 ClassPath 下指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作

                    FileSystemXmlApplicationContext:是盘下具体的一个文件,要把路径写清楚.加载指定的文件系统路径中指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作

    IOC操作Bean管理(依赖注入)

    1.什么是Bean管理

          Bean管理是两个操作:Spring创建对象和注入属性

    在了解了 IoC 之后,我们还需要了解另外一个非常重要的概念:依赖注入。

    依赖注入(Denpendency Injection,简写为 DI)是 Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩,无法让人很直接的理解“到底是哪里反转了”,因此他建议使用“依赖注入”来代替“控制反转”。

    在面向对象中,对象和对象之间是存在一种叫做“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。

    例如,有一个名为 B 的 Java 类,它的代码如下。

    1. public class B {
    2. String bid;
    3. A a;
    4. }

    从代码可以看出,B 中存在一个 A 类型的对象属性 a,此时我们就可以说 B 的对象依赖于对象 a。而依赖注入就是就是基于这种“依赖关系”而产生的。

    我们知道,控制反转核心思想就是由 Spring 负责对象的创建。在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。

    2.IOC基于xml操作Bean管理

    1、基于xml方式创建对象


              <!--配置User对象创建-->
              
             (1)在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
             (2)在bean标签有很多属性,介绍常用的属性
                     id属性:唯一标识
                     class属性:类全路径(包类路径)
             (3)创建对象时候,默认也是执行无参数构造方法完成对象创建

     2、基于xml方式注入属性-使用set方法进行注入


     (1)DI:依赖注入,就是注入属性
            第一种注入方式:使用set方法进行注入

    第一步:创建类:定义属性和对应的set方法

    1. public class Class02 {
    2. // 创建属性
    3. private String bname;
    4. private String bauthor;
    5. // 创建属性对应的set方法
    6. public void setBname(String bname){
    7. this.bname = bname;
    8. }
    9. public void setBauthor(String bauthor){
    10. this.bauthor = bauthor;
    11. }
    12. public void testDemo(){
    13. System.out.println(bname +","+bauthor);
    14. }
    15. }

    第二步:在spring配置文件中配置对象创建,配置属性注入

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id = "book" class="com.java.spring5.Class02">
    6. <property name="bname" value="诗经">property>
    7. <property name="bauthor" value="三国演义">property>
    8. bean>
    9. beans>

    第三步:测试

    1. public class Test02 {
    2. @Test
    3. public void testadd2(){
    4. // 加载配置文件
    5. ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    6. // 获取配置的创建
    7. Class02 book = context.getBean("book",Class02.class);
    8. System.out.println(book);
    9. book.testDemo();
    10. }
    11. }

    3.基于xml方式注入属性-使用有参数构造

            第一步:创建类:定义属性,创建属性对应有参数的构造方法

    1. public class Class03 {
    2. private String name1;
    3. private String bauthor1;
    4. public Class03(String name1,String bauthor1){
    5. this.bauthor1 = bauthor1;
    6. this.name1 = name1;
    7. }
    8. // 使用有参构造器进行注入
    9. public void testadd3(){
    10. System.out.println(name1 +","+ bauthor1);
    11. }
    12. }

    第二步:在spring配置文件中进行配置

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id = "book3" class="com.java.spring5.Class03">
    6. <constructor-arg name="name1" value="活着">constructor-arg>
    7. <constructor-arg name="bauthor1" value="烟草">constructor-arg>
    8. bean>
    9. beans>

    第三步:测试

    1. public class Test03 {
    2. @Test
    3. public void testaddd(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    5. Class03 book3 = context.getBean("book3",Class03.class);
    6. System.out.println(book3);
    7. book3.testadd3();
    8. }
    9. }

    4、IOC操作Bean管理xml注入其他类型属性

    (1)null值

    <property name = "address>

     (2)属性值包含特殊符号

       1把<>进行转义<: >:
        2把带特殊符号内容写到CDATA
     

    1.   <property name="address"
    2.     <value><![CDATA[<<南京>>]]value>property

    4.基于xml方式注入属性-外部注入bean方式注入属性

    1)创建两个类service类和dao类

    •         创建userDao属性并创建他的set方法

    (2)在service调用dao里面的方法        

            在配置文件中创建service对象

            创建userdao的对象

            注入UserDao的属性

    (3)在spring配置文件中进行配置。

    1. public class UserService
    2. //创建UserDao类型属性,生成set方法
    3. private UserDao userDao:
    4. public void setuserDao (UserDao userDao) {
    5. this. userDao = userDao:
    6. }
    7. public void add(
    8. System.out println(service add)
    9. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="userService" class="com.java.spring5.service.UserService">
    6. <property name="userDao" ref="userdao">property>
    7. bean>
    8. <bean id="userdao" class="com.java.spring5.dao.UserDaoEmp">bean>
    9. beans>

    5.基于xml方式注入属性-内部bean和级联赋值注入属性的方法

     (1)一对多关系:部门和员工
    一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多

    (2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行

    (3)在spring中配置

    (4)测试

    内部bean

    1. //员工类
    2. public class Emp {
    3. private Dept dept;
    4. public void setDept(Dept dept){
    5. this.dept = dept;
    6. }
    7. @Override
    8. public String toString() {
    9. return "Emp{" +
    10. "dept=" + dept +
    11. '}';
    12. }
    13. public void test(){
    14. System.out.println(dept);
    15. }
    16. }
    17. //部门类
    18. public class Dept {
    19. @Override
    20. public String toString() {
    21. return "Dept{}";
    22. }
    23. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="emp" class="com.java.spring5.bean.Emp">
    6. <property name="ename" value="lucy">property>
    7. <property name="gender" value="女">property>
    8. <property name="dept" >
    9. <bean id="dept" class="com.java.spring5.bean.Dept">
    10. <property name="dname" value="安保部">property>
    11. bean>
    12. property>
    13. bean>
    14. beans>

     级联赋值的两种写法

    1

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="emp" class="com.java.spring5.bean.Emp">
    6. <property name="ename" value="lucy">property>
    7. <property name="gender" value="女">property>
    8. <property name="dept" ref="dept1" >property>
    9. bean>
    10. <bean id="dept1" class="com.java.spring5.bean.Dept">
    11. <property name="dname" value="财务部">property>
    12. bean>
    13. beans>

            输出:lucy 女 财务部

    2

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="emp" class="com.java.spring5.bean.Emp">
    6. <property name="ename" value="lucy">property>
    7. <property name="gender" value="女">property>
    8. <property name="dept" ref="dept1" >property>
    9. <property name="dept.dname" value="技术部">property>
    10. bean>
    11. <bean id="dept1" class="com.java.spring5.bean.Dept">
    12. <property name="dname" value="财务部">property>
    13. bean>
    14. beans>

    6.xml注入集合属性

    • 注入数组类型属性
    • 注入List集合属性
    • 注入Map集合类型
    • 注入 set集合

            第一步:创建类,定义数组、list、map、set类型属性,生成对应的set方法

    1. public class Stu {
    2. // 数组类型属性
    3. private String[] courses;
    4. // List集合类型属性
    5. private List list;
    6. // Map集合类型shuxing
    7. private Map maps;
    8. // set集合类型属性
    9. private Set sets;
    10. // 学生所学的多门的课程
    11. private ListcourseList;
    12. public void setCourseList(List courseList) {
    13. this.courseList = courseList;
    14. }
    15. public void setSets(Set sets) {
    16. this.sets = sets;
    17. }
    18. public void setCourses(String[] courses) {
    19. this.courses = courses;
    20. }
    21. public void setList(List list) {
    22. this.list = list;
    23. }
    24. public void setMaps(Map maps) {
    25. this.maps = maps;
    26. }
    27. public void test(){
    28. System.out.println(Arrays.toString(courses));
    29. System.out.println(list);
    30. System.out.println(maps);
    31. System.out.println(sets);
    32. System.out.println(courseList);
    33. }
    34. }
    35. public class Course {
    36. private String cname;
    37. public void setCname(String cname) {
    38. this.cname = cname;
    39. }
    40. @Override
    41. public String toString() {
    42. return "Course{" +
    43. "cname='" + cname + '\'' +
    44. '}';
    45. }
    46. }

            第二步:在spring配置文件进行配置

    •  数组类型属性注入 标签array
    •  list属性注入  标签list
    • Map属性注入 标签map、 entry
    • set属性注入 标签set
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="stu" class="com.java.spring5.collectiontype.Stu">
    6. <property name="courses">
    7. <array>
    8. <value>javavalue>
    9. <value>数据库value>
    10. array>
    11. property>
    12. <property name="list">
    13. <list>
    14. <value>张三value>
    15. <value>李四value>
    16. list>
    17. property>
    18. <property name="maps">
    19. <map>
    20. <entry key="JAVA" value="java">entry>
    21. <entry key="PHP" value="php">entry>
    22. map>
    23. property>
    24. <property name="sets">
    25. <set>
    26. <value>mysqlvalue>
    27. <value>rediesvalue>
    28. set>
    29. property>
    30. bean>
    31. beans>

    测试

    1. public class Testc1 {
    2. @Test
    3. public void testCollectin1(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("beanc1.xml");
    5. Stu stu = context.getBean("stu", Stu.class);
    6. stu.test();
    7. }
    8. }

    但集合属性要考虑两个细节

    第一个细节:刚刚创建的都是String属性,如果我想在集合理放对象怎么放

    第二个细节:上述集合只能在id=stu中使用,不能再其他部分适用,如何提取集合将他变成公共部分

    第一个细节(list为例)

     (1)创建多个对象,和上述第一步创建内容一样

     (2)注入属性

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="cou" class="com.java.spring5.collectiontype.Stu">
    6. <property name="courseList">
    7. <list>
    8. <ref bean="course1">ref>
    9. <ref bean="course2">ref>
    10. list>
    11. property>
    12. bean>
    13. <bean id="course1" class="com.java.spring5.collectiontype.Course">
    14. <property name="cname" value="Spring5">property>
    15. bean>
    16. <bean id="course2" class="com.java.spring5.collectiontype.Course">
    17. <property name="cname" value="Mybatis">property>
    18. bean>
    19. beans>

    (3)测试

    1. public class Testc2 {
    2. @Test
    3. public void testCollection2(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("beanc2.xml");
    5. Stu stu = context.getBean("cou",Stu.class);
    6. stu.test();
    7. }
    8. }

     

    第二个细节

    (1)创建多个对象,和上述第一步创建内容一样

     (2)创建提取类book

    1. //提取类
    2. public class Book {
    3. private List list;
    4. public void setList(List list) {
    5. this.list = list;
    6. }
    7. @Override
    8. public String toString() {
    9. return "Book{" +
    10. "list=" + list +
    11. '}';
    12. }
    13. public void test3(){
    14. System.out.println(list);
    15. }
    16. }

     (3)在spring配置文件中引入名称空间util(注意上面xmlns和xsi配置)

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:p="http://www.springframework.org/schema/p"
    5. xmlns:util="http://www.springframework.org/schema/util"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    8. <util:list id="bookList">
    9. <value>value>
    10. <value>value>
    11. <value>value>
    12. util:list>
    13. <bean id="book" class="com.java.spring5.collectiontype.Book">
    14. <property name="list" ref="bookList">property>
    15. bean>
    16. beans>

    (4)测试

    1. public class Testc3 {
    2. @Test
    3. public void testCollectin3(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("beanc3.xml");
    5. Book bo = context.getBean("book", Book.class);
    6. bo.test3();
    7. }
    8. }

    7.工厂bean-FactoryBean 


           1、Spring有两种类型bean,一种普通bean,另外一种工厂bean-FactoryBean 
            2、普通bean:在配置文件中定义bean类型就是返回类型(上面的就是普通的)
            3、工厂bean:在配置文件定义bean类型可以和返回类型不一样
                 第一步创建类,让这个类作为工厂bean,实现接口FactoryBean 

                  第二步实现接口里面的方法,在实现的方法中定义返回的bean类型

    1. //实现factorybean实现接口
    2. public class MyBean implements FactoryBean {
    3. //返回类型方法,你定义的类型和返回类型不一样是由此方法决定
    4. // 类里定义的是MyBean类型,返回Course类型
    5. @Override
    6. public Course getObject() throws Exception {
    7. Course course = new Course();
    8. course.setCname("abc");
    9. return course;
    10. }
    11. //返回类型
    12. @Override
    13. public Class getObjectType() {
    14. return null;
    15. }
    16. //是否是一个单例
    17. //单例:所有请求都有一个对象来处理,因为没必要每个请求都建一个对象
    18. @Override
    19. public boolean isSingleton() {
    20. return FactoryBean.super.isSingleton();
    21. }
    22. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="mybean" class="com.java.spring5.factorybean.MyBean">bean>
    6. beans>
    1. public class Testf1 {
    2. @Test
    3. public void testf1(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("beanf.xml");
    5. // 注意.class调用的类名,是返回值的类型
    6. Course mybean = context.getBean("mybean", Course.class);
    7. System.out.println(mybean);
    8. }
    9. }

     8.bean创建单例和多利

    在Spring里,默认情况下,bean是单例

             Book1和 Book2输出内容相同

    如何设置单例还是多例
    (1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
    (2)scope属性值
    第一个值默认值,singleton,表示是单实例对象
    第二个值prototype,表示是多实例对象

    singleton和prototype区别
    第一 singleton单实例,prototype多实例
    第二设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象+
           设置scope值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象 

    8.、bean生命周期

    生命周期
     (1)从对象创建到对象销毁的过程
     2、bean生命周期,无后置配置处理器时
     (1)通过构造器创建bean实例(无参数构造)
     (2)为bean的属性设置值和对其他bean引用(调用set方法)
      (3)调用bean的初始化的方法(需要进行配置初始化的方法)
      (4)bean可以使用了(对象获取到了)
      (5)当容器关闭时候,词用bean的销毁的方法(需要进行配置销毁的方法)

    1. public class Orders {
    2. private String oname;
    3. public Orders() {
    4. System.out.println("第一步:执行无参构造器创建bean实例");
    5. }
    6. public void setOname(String oname) {
    7. this.oname = oname;
    8. System.out.println("第二步:调用set方法设置属性值");
    9. }
    10. // 创建执行初始化的方法,但这只是一个普通的方法不会自己执行所以我们要进行配置
    11. public void initMethod(){
    12. System.out.println("执行初始化的方法");
    13. }
    14. // 销毁方法
    15. public void destory(){
    16. System.out.println("第五步:这是一个销毁方法");
    17. }
    18. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="orders" class="com.java.spring5.bean.Orders" init-method="initMethod" destroy-method="destory">
    6. <property name="oname" value="手机">property>
    7. bean>
    8. beans>
    1. public class Testl1 {
    2. @Test
    3. public void life(){
    4. // ApplicationContext不能调用close方法他的子类可以ClassPathXmlApplicationContext
    5. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanl1.xml");
    6. Orders orders = context.getBean("orders", Orders.class);
    7. System.out.println("第四步:获取创建bean实例对象");
    8. System.out.println(orders);
    9. // 手动销毁bean实例才能让配置调用
    10. context.close();
    11. }

    9.Bean的后置处理器 

    bean有后置处理器,bean生命周期有七步
     (1)通过构造器创建bean实例(无参数构造)
     ( 2)为bean的属性设置值和对其他bean引用(调用set方法)t
     (3)把bean实例传递bean后置处理器的方法postProessAfternitialization

     (4)调用bean的初始化的方法(需要进行配置初始化的方法)
    (5))把bean实例传递bean后置处理器的方法postProessAfternitialization
    (6)bean可以使用了(对象获取到了)
    (7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)
    演示添加后置处理器效果
    1)创建类,实现接口BeanPostProessor 创建后置处理器

    1. public class Orders {
    2. private String oname;
    3. public Orders() {
    4. System.out.println("第一步:执行无参构造器创建bean实例");
    5. }
    6. public void setOname(String oname) {
    7. this.oname = oname;
    8. System.out.println("第二步:调用set方法设置属性值");
    9. }
    10. // 创建执行初始化的方法,但这只是一个普通的方法不会自己执行所以我们要进行配置
    11. public void initMethod(){
    12. System.out.println("执行初始化的方法");
    13. }
    14. // 销毁方法
    15. public void destory(){
    16. System.out.println("第五步:这是一个销毁方法");
    17. }
    18. }
    19. public class MyBeanFost implements BeanPostProcessor {
    20. @Override
    21. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    22. System.out.println("这是初始化之前执行的方法");
    23. return bean;
    24. }
    25. @Override
    26. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    27. System.out.println("这是初始化之后执行的方法");
    28. return bean;
    29. }
    30. }
    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="orders" class="com.java.spring5.bean.Orders" init-method="initMethod" destroy-method="destory">
    6. <property name="oname" value="手机">property>
    7. bean>
    8. <bean id="myBeanPost" class="com.java.spring5.bean.MyBeanFost">bean>
    9. beans>
    1. public class Testl1 {
    2. @Test
    3. public void life(){
    4. // ApplicationContext不能调用close方法他的子类可以ClassPathXmlApplicationContext
    5. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanl1.xml");
    6. Orders orders = context.getBean("orders", Orders.class);
    7. System.out.println("第四步:获取创建bean实例对象");
    8. System.out.println(orders);
    9. // 手动销毁bean实例才能让配置调用
    10. context.close();
    11. }

     

    10.xml自动装配

    什么是自动装配
    (1)根据指定装配规则(属性名称或者属性类),Spring自动将匹配的属性值进行注入 

    根据属性名或类型自动注入 

     第一步:创建类和属性

    1. public class Emp {
    2. private Dept dept;
    3. public void setDept(Dept dept){
    4. this.dept = dept;
    5. }
    6. @Override
    7. public String toString() {
    8. return "Emp{" +
    9. "dept=" + dept +
    10. '}';
    11. }
    12. public void test(){
    13. System.out.println(dept);
    14. }
    15. }
    16. public class Dept {
    17. @Override
    18. public String toString() {
    19. return "Dept{}";
    20. }
    21. }

     第二步:配置xml属性

     实现自动装配
            bean标签属性autowire实现自动装配
            这个属性有两个值:byName根据属性名称注入,注入bean的值必须和类的属性名称一样
            byType:根据属性类型注入,同一个类型只能注册一次

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="emp" class="com.java.spring5.autowire.Emp" autowire="byName">
    6. bean>
    7. <bean id="dept" class="com.java.spring5.autowire.Dept" >bean>
    8. beans>

    11.     IOC操作Bean管理(外部属性文件-数据库)


              1、直接配置数据库信息
                    1)配置德鲁伊连接池
                     2)引入德鲁伊连接池依赖jar包

                   2.引入外部属性文件配置数据库连接池

                    1)创建外部属性文件,properties格式文件,写数据库信息

    1. prop.driverClass=com.mysql.cj.jdbc.Driver
    2. prop.url=jdbc:mysql://localhost:3306/test
    3. prop.name=root
    4. prop.password=123456

                    2)把外部properties属性文件引入到Spring配置文件中

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:p="http://www.springframework.org/schema/p"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd">
    8. <bean id="dtaSocutse" class="com.alibaba.druid.pool.DruidDataSource">
    9. <property name="driverClassName" value="${prop.driverClass">property>
    10. <property name="url" value="${prop.url">property>
    11. <property name="username" value="${prop.name">property>
    12. <property name="password" value="${prop.password">property>
    13. bean>
    14. beans>

     基于注解方式操作bean管理

         1、什么是注解


              1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值..)
               2)使用注解,注解作用在类上面,方法上面,属性上面
               3)使用注解目的:简化xml配置


        2.Spring针对Bean管理中创建对象提供注解


             1)@Component:普通组建利用它都可以创建对象
              2)@Service:一般用在业务逻辑和service层
              3)@Controllei:用在web层
             4)@Repository:dao层

    四者使用时没什么区别,都是用来创建对象的且参数都为value,value为此bean的名字可不写,默认为第一个字母为小写的类名


    3、基于注解方式实现对象创建


    第一步引入依赖

    第二步开启组件扫描

    context:component-scan:关键字扫描

    base-package:要扫描的包名
       如果扫多个包,多个包使用号隔开  或扫描包上层目录

    
    
    第三步创建类,在类上面添加创建对象注解
     在注解里面value属性值可以省略不写,
     默认值是类名称,首字母小写

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:p="http://www.springframework.org/schema/p"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    8. <context:component-scan base-package="com.java.spring5">context:component-scan>
    9. beans>
    1. //使用注解创建对象可使用四个注解中任何一个
    2. //在注解里面的value可以省略不写,他会默认类名的首字母小写
    3. @Service(value = "userService")
    4. public class UserService {
    5. // 定义dao属性不需要添加set方法,添加属性注解即可
    6. public void add(){
    7. System.out.println("service add....");
    8. }
    9. }

     测试

    1. public class TestZhujie {
    2. @Test
    3. public void testServices(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("beanzhu1.xml");
    5. // 这里不在是id值,因为value值相当于id值
    6. UserService userService = context.getBean("userService", UserService.class);
    7. System.out.println(userService);
    8. userService.add();
    9. }
    10. }

     细节:扫描类的选择

    红色:扫描包中的所有类

    彩色:扫描Controller注解中的所有类

     

    其中type有annotation,aspectj,assignable,custom,regex几种类型。

    其意义如下: 

    annotation:注解类型
    assignable_type:annotation:指定的类型
    aspectj:按照Aspectj的表达式,基本上不会用到
    regex:按照正则表达式
    custom:自定义规则

    4、基于注解方式实现属性注入

    (1)@Autowired:根据属性类型进行自动装配
     (2)@Qualifier:根据属性名称进行注入
     (3) @Resource: 可以根据类型注入,可以根据名称注入
      (4) @value:注入普通类型属性

    5、基于注解方式实现属性注入

    (1)@Autoired根据属性类型进行自动装配
    第一步service和dao对象创建,在senvice和dao类添加创建对象注解(@Service @Repository )

    第二步在service注入da0对象,在sevice类添加dao类型属性,在属性上面使用注解(   @Autowired)

    1. @Service
    2. public class UserService {
    3. // 定义接口属性,不需要添加set方法,添加注入属性注解
    4. @Autowired
    5. private UserDao userDao;
    6. public void add(){
    7. System.out.println("service add...");
    8. userDao.add1();
    9. }
    10. }
    11. public interface UserDao {
    12. public void add1();
    13. }
    14. @Repository
    15. public class UserDaoEmp1 implements UserDao {
    16. @Override
    17. public void add1() {
    18. System.out.println("dao");
    19. }
    20. }

    测试

    1. public class Test1 {
    2. @Test
    3. public void testServices(){
    4. ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    5. // 这里不在是id值,因为value值相当于id值
    6. UserService userService = context.getBean("userService", UserService.class);
    7. System.out.println(userService);
    8. userService.add();
    9. }
    10. }

     (2)@Qualifier:根据属性名称进行注入(但必须结合@Autowired使用)

             当有多个接口实现类时Autowired没有办法确定是哪个实现类。所以结合@Qualifier根据名称进行注解

    (3)  @Resource: 可以根据类型注入,可以根据名称注入

     

     4) @value:注入普通类型属性


           输出:   name = abc 

    完全注解开发(了解SpringBoot会真正涉及)

            

  • 相关阅读:
    Copilot:AI自动写代码,人工智能究竟还能取代什么?
    SCI论文写作(一) | SCI论文的文献综述(Literature Review)部分
    Visual Studio 线性表的链式存储节点输出引发异常:读取访问权限冲突
    Pandas文本处理
    你不知道的JavaScript---异步:现在与未来
    炸机不可怕,可怕的是你不知道为什么炸
    hadoop宕机的处理方法
    一文讲透 RocketMQ 消费者是如何负载均衡的
    【目标锁定特效】(Html+JS+CSS+效果+代码)
    【JAVA基础——JAVA虚拟机JVM】
  • 原文地址:https://blog.csdn.net/m0_56223907/article/details/126881082