IOC容器

1. IOC基本概念:

  1. 控制反转(Inversion of Control,缩写为IoC
  2. 使用IOC目的是为了降低耦合度

2. IOC底层原理

  1. xml解析、工厂模式、反射

3. IOC(接口)

1. BeanFactory

IOC容器的基本实现,是Spring内部的使用接口,不提供开发人员进行使用。
区别:(加载配置文件时不创建对象,在获取对象(使用时)才创建对象)

2. ApplicationContext(一般用这种方式):

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

3. IOC操作Bean管理

1. 什么是Bean管理

  • Spring创建对象
  • Spring注入属性

2. Spring 有两种类型的 bean

  1. 普通bean:在配置文件中定义的bean类型就是返回类型。(定义什么返回什么)

    1. 创建类,创建配置文件

      <!--创建类对象--> <bean id="mybean" class="com.wnaoii.spring5.factorybean.Mybean"></bean>
    2. 测试类测试

      public class TestDemo { @Test public void testDemo() { ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); // 普通bean:创建什么类型返回什么类型 Mybean myBean = context.getBean("mybean",Mybean.class); System.out.println(myBean); } }
  2. 工厂bean(FactoryBean):在配置文件中定义的bean类型可以和返回的类型不一样(多态?)

    1. 创建类,让这个类作为工厂bean,实现接口 FactoryBean
    2. 实现接口里面的方法,在实现的方法中定义返回的bean类型

3. Bean管理的实现方式

1. 基于 xml 配置文件方式实现
  1. 创建对应的bean.xml文件中使用bean标签,标签里添加对应的属性,即可实现对象的创建。

  2. 创建对象的时候也是默认执行无参构造器完成对象创建。

  3. x 1<!--配置User对象创建-->2<bean id="user" class="com.wnaoii.User"/>
  4. 在Bean标签中有许多属性,这里介绍下常用属性

    • id属性:唯一标识,在bean中生成对象的别名。
    • class属性:类全路径(包类路径)
2. Bean管理 xml 方式(注入属性)
  • xml 的注入方式也是通过get/set方法注入
  1. 使用set方法注入

    1. 常规方式

      public class Book { // 创建属性 private String bname; // 属性对应的set方法 public void setBname(String bname) { this.bname = bname; } public static void main(String[] args) { // 建对象 Book book = new Book(); // 注入值 book.setBname("xiaoming"); System.out.println(book.bname); } }
    2. xml配置文件方式

      • 写好xml配置文件

        <!--配置User对象创建--> <bean id="book" class="com.wnaoii.Book"> <!-- 在bean标签中使用property完成属性注入 name:类里属性的名字 value:需要注入的值 --> <property name="bname" value="xiaoming"></property> </bean>
      • 调用xml配置文件

        public class TestSpring5 { @Test public void testAdd() { // 1.加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // 2.获取配置创建的对象 Book book = context.getBean("book",Book.class); // getBean中”book“为xml配置的对象,Book.class表示转换的类型 book.pringtName(); System.out.println(book); } }
  2. 有参构造注入

    1. 常规方式

      public class Book { // 创建属性 private String bname; public Book() { } // 有参构造 public Book(String bname) { this.bname = bname; } public static void main(String[] args) { // 建对象,有参构造注入值 Book book = new Book("xiaogang"); System.out.println(book.bname); } }
    2. xml配置文件方式

      1. 创建类,定义属性,创建对应的有参构造器

        public class orders { private String oname; private String address; // 无参构造不写也行? public orders() { } // 有参构造 public orders(String oname, String address) { this.oname = oname; this.address = address; } }
      2. 配置好xml配置文件里的Bean标签

        <!-- 在bean标签中使用constructor-arg完成属性注入 name:类里属性的名字 value:需要注入的值 --> <bean id="orders" class="com.wnaoii.Orders"> <constructor-arg name="oname" value="手机"></constructor-arg> <constructor-arg name="address" value="中国"></constructor-arg> </bean>
      3. 测试类中测试

        public class TestSpring5 { @Test public void testOrders() { // 1.加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); // 2.获取配置创建的对象 Orders orders = context.getBean("orders", Orders.class); orders.testOrders(); System.out.println(orders); } }
  3. P名称空间注入(了解)

    1. 使用 p 名称空间注入,可以简化基于 xml 配置方式
3. Bean管理 xml 方式(注入其他类型属性)
1. 字面量
  1. null 值

    • 不注入值也为属性的值也为null,写了增加程序的可读性。大概?

    • xml 配置文件中不设值添加<null/>标签

      <!--null值--> <property name="address"> <null/> </property>
    • address 属性中注入的值就设置为null(空)

  2. 属性包含特殊符号

    • 两种方法:

      1. 将特殊符号进行转义&lt; &gt;,再注入。

      2. 将带特殊符号的内容写到CDATA

        <!--注入"<<上海>>"这个值--> <property name="address"> <value><![CDATA[<<上海>>]]></value> </property>
4. Bean管理 xml 方式(注入外部Bean)
1. 注入属性-外部bean
  1. 创建两个类service类和dao

    1. service

      public class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
    2. dao

      public class UserDaoImp implements UserDao{ @Override public void update() { System.out.println("UserDao Update已运行!"); } }
  2. service调用dao里面的方法

    public class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void printUserService(){ // 调dao里的方法 userDao.update(); System.out.println("UserService已运行!"); } }
  3. 在Spring配置文件中进行配置

    <!--配置User对象创建--> <bean id="userDao" class="com.wnaoii.dao.UserDaoImp"></bean> <bean id="userService" class="com.wnaoii.service.UserService"> <!-- 注入userDao对象 name属性:类里面属性的名称 ref:刚创建的userDao对象的bean标签的id值 --> <property name="userDao" ref="userDao"></property> </bean>
  4. 在测试类中测试

    public class TestBean { @Test public void Test(){ // 1.加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("Bean2.xml"); // 2.获取配置文件中创建的对象 UserService userService = context.getBean("userService",UserService.class); userService.printUserService(); } }
2. 注入属性-内部Bean
  1. 一对多关系:部门和员工

    • 一个部门包含多个员工
    • 一个员工属于一个部门
  2. 在实体类中表示一对多的关系

    • 部门类

      // 部门类 public class Dept { private String dName; public void setdName(String dName) { this.dName = dName; } }
    • 员工类

      // 员工类 public class Emp { private String eName; private String gender; // 员工属于某一个部门,使用对象的形式表示 private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void seteName(String eName) { this.eName = eName; } public void setGender(String gender) { this.gender = gender; } }
  3. 在 spring 配置文件中进行配置

    <!--员工类对象创建--> <bean id="emp" class="com.wnaoii.bean.Emp"> <!--设置两个普通的属性--> <property name="eName" value="小明"></property> <property name="gender" value="男"></property> <!--设置对象类型的属性--> <property name="dept"> <!--内部再嵌套一个对象--> <bean id="dept" class="com.wnaoii.bean.Dept"> <property name="dName" value="保安部"></property> </bean> </property> </bean>
3. 注入属性-级联赋值
  • 和外部bean的区别就是在外部bean中赋值再传入

    <!--级联赋值--> <bean id="emp" class="com.wnaoii.bean.Emp"> <!--设置两个普通的属性--> <property name="eName" value="小明"></property> <property name="gender" value="男"></property> <!--级联赋值--> <property name="dept" ref="dept"></property> </bean> <!--创建外部bean并赋值--> <bean id="dept" class="com.wnaoii.bean.Dept"> <property name="dName" value="财务部"></property> </bean>
5.Bean管理 xml 方式(注入集合类型属性)
1. 注入数组类型属性
  • xml配置文件中创建对象

  • 使用<array>标签注入

    <bean id="创建的对象名" class="类路径"> <property name="courses"> <array> <!--填写注入的值--> <value>注入的值</value> </array> </property> </bean>
2. 注入 List 集合类型属性
  • 同上大同小异,List集合类型就用List标签注入

    <bean id="创建的对象名" class="类路径"> <property name="courses"> <list> <!--填写注入的值--> <value>注入的值</value> </list> </property> </bean>
3. 注入 Map 集合类型
  • 使用标签注入

    <bean id="创建的对象名" class="类路径"> <property name="courses"> <map> <!--填写注入的值--> <entry key="" value=></entry> </map> </property> </bean>
4. 在集合里面设置对象类型值

(用上再看)

5. 把集合注入部分提取出来
  • 使用util标签

    <util:list id="list1"> <value>java</value> <value>python</value> <value>jsp</value> </util:list>
  • 创建好后直接在xml配置文件创建的对象中应用

    <bean id="student" class="com.wnaoii.spring5.collectiontype.student"> <property name="courses" ref="list1"></property> </bean>
6. 基于注解方式实现
  1. 什么是注解

    1. 注解是代码的特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值......)
    2. 使用注解,注解作用在类上面,方法上面,属性上面
    3. 注解的目的:简化 xml 配置
  2. Spring针对Bean管理中创建对象提供的注解

    1. @Conponent
    2. @Service
    3. @Controller
    4. @Repository

    以上四个注解实现的功能是一样的,都可以用来创建Bean的实例,名称只是用来区分在哪个层

  3. 基于注解的方式创建对象

    1. 引入依赖

    2. 开启组件扫描

      • 使用注解创建一定要配置开启扫描

      • 在 xml 配置文件中开启

        <context:component-scan base-package="com.wnaoii.spring5.testDemo"></context:component-scan>
      • base-package的值是扫描的包路径,扫描的包可以添加逗号隔开,也可以扫描整个包路径。

    3. 创建对象

      1. 创建一个类的开头添加注解

        @Service(value = "userServic") public class UserService { public void testDemo(){ System.out.println("testDemo运行中-----"); } }
        • value的值就相当于xml配置文件中<bean>标签里的id值
        • value的值不写默认为类名首字母小写
      2. 测试类中测试

        public class TestDemo { @Test public void testService() { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); UserService userServic = context.getBean("userServic", UserService.class); userServic.testDemo(); System.out.println(userServic); } }
  4. 基于注解的方式注入属性

    1. 常用的注入属性的注解

      • @AutoWired:根据属性类型进行自动装配

        1. 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象的注解

          • UserService

            @Repository public class UserService { public void testDemo(){ System.out.println("testDemo运行中-----"); } }
          • UserDao

            @Repository public class UserDaoImpl implements UserDao{ @Override public void add() { System.out.println("add方法正在运行-----"); } }
        2. 在 service 注入 dao 对象

          • 在 service 类添加 dao 类型的属性,在属性上面使用注解

            @Service(value = "userServic") @Repository public class UserService { // 定义dao类型属性 // 不需要添加set方法 // 添加注入属性注解 @Autowired private UserDao userDao; public void testDemo(){ System.out.println("testDemo运行中-----"); // 调dao里的方法 userDao.add(); } }
      • @Qualifier:根据属性名称进行注入

        • 这个注解得和上面的@AutoWired注解一起使用

        • @AutoWired注解根据类型注入,如果一个接口有多个实现类,@Qualifier就能指定名称注入指定的实现类

          @Service(value = "userServic") @Repository public class UserService { @Autowired @Qualifier(value = "注入实现类的名称") // 根据名称注入 private UserDao userDao; public void testDemo(){ System.out.println("testDemo运行中-----"); // 调dao里的方法 userDao.add(); } }
      • @Resource:可以根据属性类型注入,也可以根据名称注入

        • 根据类型注入

          @Service(value = "userServic") @Repository public class UserService { // 和@AutoWired注解使用方法一致 @Resource private UserDao userDao; public void testDemo(){ System.out.println("testDemo运行中-----"); userDao.add(); } }
        • 根据名称注入

          @Service(value = "userServic") @Repository public class UserService { // 参考@Qualifier注解的使用,只不过value改为name @Resource(name = "userDaoImpl1") private UserDao userDao; public void testDemo(){ System.out.println("testDemo运行中-----"); userDao.add(); } }
        • @Resource注解集合了@AutoWired@Qualifier注解

        • @Resource注解不是Spring官方包里的,是javax包中的,官方更推荐使用@AutoWired@Qualifier注解

      • @Value:注入普通类型属性

        • 在需要注入的地方上加上注解

          @Value(value = "小名") private String name;
        • @Value注解有点脱裤子放屁的感觉?直接赋值不香?

  5. 纯注解开发

    1. 创建配置类,替代 xml 配置文件

      • @Configuration注解可以标识这个类为配置类
      • @ComponentScan注解代替xml配置文件的开启组件扫描
      @Configuration // 设置为配置类,替代xml配置文件 @ComponentScan(basePackages = {"com.wnaoii"}) // 需要扫描包的路径 public class SpringConfig { }
    2. 编写测试类

      • AnnotationConfigApplicationContext里的值是配置类的名称
      public class TestDemo { @Test public void testService() { // 加载配置类 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userServic = context.getBean("userServic", UserService.class); userServic.testDemo(); System.out.println(userServic); } }

4. Bean 的作用域

  1. 在 Spring 里面,默认创建单实例对象。(每次获取该对象都是同一地址)

  2. 在 Spring 里面,可以设置创建bean实例是单实例还是多实例(每次获取该对象都是不同的地址,创个新的)

    1. 在 Spring 配置文件bean标签里面有属性scope用于设置单实例还是多实例

    2. scope属性值(常用值)

      • singleton(默认值):表示单实例对象,

      • prototype:表示多实例对象,

        <!--添加 scope 属性值就是一个多实例对象--> <bean id="mybean" class="com.wnaoii.spring5.factorybean.Mybean" scope="prototype"></bean>
  3. singletonprototype的区别

    • scope值为singleton时,加载spring配置文件时就会创建对象
    • scope值为prototype时,加载spring配置文件时不会创建对象,在调用 getBean 方法的时候才创建多实例对象

5. bean 生命周期

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

6. XML 自动装配

  1. 什么是自动装配

    • 根据指定装配额规则(属性名称或者属性类型), Spring 自动将匹配的属性进行注入
  2. 使用autowire属性实现自动装配

    <bean id="emp" class="com.wnaoii.spring5.autowire.Emp" autowire="byName">
  3. autowire属性常用值:

    • byName:根据属性名称注入(注入值bean的id值要和类属性的名称一致)
    • byType:根据属性类型注入

__EOF__

本文作者WNAOII
本文链接https://www.cnblogs.com/WNAOII/p/15252841.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   WNAOII  阅读(126)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示