Spring之IOC容器(带你一篇文章搞定IOC)

简介: Spring之IOC容器(带你一篇文章搞定IOC)



前言

Spring框架的核心就是IOC和AOP,本篇文章就讲述一下其中的IOC容器。(这是听尚硅谷课程总结的)


一、IOC概述及底层原理

1.概述和原理

  • IOC是控制反转的意思。使用对象时候由主动new对象转换成由外部提供对象,此过程中对象的创建权由程序转移到外部,这种思想叫做控制反转。即把对象创建和对象的调用过程交给spring进行管理。
  • 目的:降低耦合度。
  • 底层原理:xml配置,反射,工厂模式。
  • Spring提供IOC容器两种实现方式(两个接口)
    (1)BeanFactory:Spring内部使用的接口,不提倡开发人员使用。特点:加载配置文件时不会创建对象,获取对象时才会创建对象。
    (2)ApplicationContext:BeanFactory的子接口,提供了更多更强大的功能,一般由开发人员使用。特点:加载配置文件时会把配置文件里的对象进行创建。
    (3)核心:Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的外部
    IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IOC容器中统称为Bean。
  • ApplicationContext两个常用的实现类:
    (1)FileSystemXmlApplicationContext:绝对路径,从盘符开始算起
    (2)ClassPathXmlApplicationContext:相对路径,从项目的src开始算起
  • IOC实现:依赖注入,即在容器中建立bean与bean之间的依赖关系的整个过程。

二、思路分析

  • IOC管理什么(bean对象)
  • 如何告知IOC去管理bean对象(通过配置文件)
  • 被管理的对象交给IOC容器,如何获取IOC容器?(接口)
  • IOC容器得到后,如何获取bean?(通过ApplicationContext接口的两个实现类的getBean方法获取bean实例创建对象)

三、IOC操作bean管理(基于xml,使用的是IDEA2022.3.3,maven仓库)

首先告诉大家本篇文章的所有使用的spring依赖版本:

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>6.0.9</version>
        </dependency>
    </dependencies>

1.xml实现bean管理

(1)创建对象

项目的resource资源文件夹创建spring的配置文件,然后添加如下代码:

<bean id="book" class="com.dragon.spring5.Book"></bean>
  • id:创建对象的名称
  • class:Book类的路径
  • 创建对象时默认是执行无参构造函数

(2)注入属性

创建对象后,对象内的属性还没有赋值等等,讲诉三种注入属性得到方式:

  • 第一种:set方法注入
    这种方法需要类的属性有对应的set方法,如下:
public class Book {
    private String bname;
    private String bauthor;
    public void setBname(String bname) {
        this.bname = bname;
    }
    public void setBauthor(String bauthor) {
        this.bauthor = bauthor;
    }
    public void testbook(){
        System.out.println(bname+":"+bauthor);
    }
}

然后在spring配置文件中通过property标签进行属性注入,如下:

<bean id="book" class="com.dragon.spring5.Book">
      <property name="bname" value="易筋经"></property>
            <property name="bauthor" value="达摩老祖"></property>
</bean>

然后测试:

<!--加载spring配置文件创建对象-->
  ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
  <!--反射-->
  Book book=context.getBean("book", Book.class);
  System.out.println(book);
  book.testbook();

  • 第二种:有参构造方法注入
    提供有参构造方法:
public class Book {
    private String bname;
    private String bauthor;
    public Book(String bname, String bauthor) {
        this.bname = bname;
        this.bauthor = bauthor;
    }
    public void testbook(){
        System.out.println(bname+":"+bauthor);
    }
}

然后在spring配置文件中,如下:

<bean id="book" class="com.dragon.spring5.Book">
          <constructor-arg name="bname" value="易筋经"></constructor-arg>
          <constructor-arg name="bauthor" value="达摩老祖"></constructor-arg>
</bean>

(3)p名称空间注入

set方法、测试的代码跟上诉一样,不再赘诉。

在spring配置文件中添加p名称空间,和配置代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       <!--添加p名称空间-->
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="book" class="com.dragon.spring5.Book" p:bname="九阴神功" p:bauthor="无名氏"></bean></beans>

(4)其他注入

1.注入的属性值是null或者有符号,如下:
<bean id="book" class="com.dragon.spring5.Book">
                <property name="bauthor">
                        <null/>
                </property>
                <property name="bname">
                        <value><![CDATA[<<读者>>]]></value>
                </property>
        </bean>
  • 有符号:用<![CDATA[带符号的属性值(包括符号)]]>
  • 空值:< null />

2.注入外部bean,如下:

spring配置文件:

  • ref:引用外部bean的id值
<bean id="userService" class="com.dragon.spring5.service.UserService">
        <property name="userDao" ref="userDaoImpl"></property>
    </bean>
    <bean id="userDaoImpl" class="com.dragon.spring5.dao.UserDaoImpl"></bean>

UserService、UserDao、UserDaoImpl、测试类代码:

package com.dragon.spring5.dao;
public interface UserDao {
    public void update();
}
=============================================================
package com.dragon.spring5.dao;
public class UserDaoImpl implements UserDao{
    @Override
    public void update() {
        System.out.println("dao update.......");
    }
}
=========================================================
package com.dragon.spring5.service;
import com.dragon.spring5.dao.UserDao;
public class UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void add(){
        System.out.println("service add........");
        userDao.update();
    }
}
======================================================
ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
UserService userService=context.getBean("userService", UserService.class);
userService.add();

3.内部bean注入

不通过ref属性,而是通过嵌套一个bean标签实现

spring配置文件:

<bean id="emp" class="com.dragon.spring5.bean.Emp">
            <property name="enanme" value="lucy"></property>
            <property name="gender" value="女"></property>
            <property name="dept">
                <bean id="dept" class="com.dragon.spring5.bean.Dept">
                    <property name="dname" value="保安部门"></property>
                </bean>
            </property>
        </bean>

Emp、Dept、测试类代码:

package com.dragon.spring5.bean;
public class Emp {
    private String enanme;
    private String gender;
    private Dept dept;
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    public void setEnanme(String enanme) {
        this.enanme = enanme;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public void add(){
        System.out.println(enanme+"::"+gender+"::"+dept);
    }
}
===================================================================
package com.dragon.spring5.bean;
public class Dept {
    private String dname;
    public void setDname(String dname) {
        this.dname = dname;
    }
    @Override
    public String toString() {
        return "Dept{" +
                "dname='" + dname + '\'' +
                '}';
    }
}
==========================================================================
ApplicationContext context1=new ClassPathXmlApplicationContext("bean2.xml");
        Emp emp=context1.getBean("emp", Emp.class);
        emp.add();

4.级联赋值

写法一:也就是上面所说的外部bean,通过ref属性来获取外部bean

写法二:

emp类中有ename和dept两个属性,其中dept有dname属性,写法二需要emp提供dept属性的get方法。

<bean id="emp" class="com.dragon.spring5.bean.Emp">
                    <property name="enanme" value="john"></property>
                    <property name="gender" value="男"></property>
                    <!--写法一-->
                    <property name="dept" ref="dept"></property>
                    <!--写法二-->
                    <property name="dept.dname" value="技术部"></property>
                </bean>
                <bean id="dept" class="com.dragon.spring5.bean.Dept">
                    <property name="dname" value="财务部"></property>
                </bean>
5.注入集合

stu类:

package com.dragon.spring5.collectiontype;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Stu {
    private String[] courses;
    private List<String> list;
    private Map<String,String> maps;
    private Set<String> sets;
    private List<Course> courselist;
    public void setCourselist(List<Course> courselist) {
        this.courselist = courselist;
    }
    public void setSets(Set<String> sets) {
        this.sets = sets;
    }
    public void setCourses(String[] courses) {
        this.courses = courses;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }
    public void test(){
        System.out.println(Arrays.toString(courses));
        System.out.println(list);
        System.out.println(maps);
        System.out.println(sets);
        System.out.println(courselist);
    }
}

Course类:

package com.dragon.spring5.collectiontype;
public class Course {
    private String cname;
    public void setCname(String cname) {
        this.cname = cname;
    }
    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}

spring配置文件:

<bean id="stu" class="com.dragon.spring5.collectiontype.Stu">
        <property name="courses">
            <array>
                <value>java课程</value>
                <value>数据库课程</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>张三</value>
                <value>小三</value>
            </list>
        </property>
        <property name="maps">
            <map>
                <entry key="JAAVA" value="java"></entry>
                <entry key="PHP" value="php"></entry>
            </map>
        </property>
        <property name="sets">
            <set>
                <value>MySQL</value>
                <value>Redis</value>
            </set>
        </property>
        <!--外部bean注入-->
        <property name="courselist">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
</bean>
<bean id="course2" class="com.dragon.spring5.collectiontype.Course">
       <property name="cname" value="MyBatis框架"></property>
</bean>

测试:

ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");
        Stu stu=context.getBean("stu", Stu.class);
        stu.test();

集合提取出来注入:

用util标签(注意util标签怎么引入):

Book类:

package com.dragon.spring5.collectiontype;
import java.util.List;
public class Book {
    private List<String> list;
    public void setList(List<String> list) {
        this.list = list;
    }
    public void test(){
        System.out.println(list);
    }
}
<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
        <util:list id="booklist">
            <value>易筋经</value>
            <value>九阳神功</value>
            <value>九阴真经</value>
        </util:list>
        <bean id="book" class="com.dragon.spring5.collectiontype.Book" scope="prototype">
            <property name="list" ref="booklist"></property>
        </bean>
</beans>

(5)FactoryBean(工厂bean)

普通bean在配置文件中定义的bean类型就是返回类型。而工厂bean在配置文件定义的bean类型可以和返回类型不一样。

下面的MyBean类中实现FactoryBean接口,重写getObject,getObjectType方法。

这里把getObject重写成返回Course对象的方法。

package com.dragon.spring5.factorybean;
import com.dragon.spring5.collectiontype.Course;
import org.springframework.beans.factory.FactoryBean;
public class MyBean implements FactoryBean<Course> {
    @Override
    public Course getObject() throws Exception {
        Course course=new Course();
        course.setCname("abc");
        return course;
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

spring配置文件:

<bean id="mybean" class="com.dragon.spring5.factorybean.MyBean"></bean>

测试:

注意这里实例化对象不是MyBean类型,是上面getObject方法返回的对象类型。

ApplicationContext context=new ClassPathXmlApplicationContext("bean5.xml");
        Course course=context.getBean("mybean", Course.class);
        System.out.println(course);

2.bean的作用域

  • 在Spring中,默认情况下bean创建的是单实例对象:
ApplicationContext context1=new ClassPathXmlApplicationContext("bean4.xml");
        Book book1=context1.getBean("book", Book.class);
        Book book2=context1.getBean("book", Book.class);

可以看出地址一样

  • bean有个属性是scope,可以通过设置成singleton或prototype来决定其是单实例还是多实例(1)singleton:默认值,表示单实例对象。加载配置文件时就会创建单实例对象。
    (2)prototype:表示多实例对象。不是在加载配置文件时创建对象,在调用getBean方法时创建多实例对象。
<bean id="book" class="com.dragon.spring5.collectiontype.Book" scope="prototype">
            <property name="list" ref="booklist"></property>
</bean>

  • scope的值还可以是request、session(大家应该知道这两个值的作用域吧)

3.bean的生命周期

(1)通过构造器创建 bean 实例(无参数构造)

(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization

(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization

(6)bean 可以使用了(对象获取到了)

(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

下面提供大家测试需要用的类,方便大家理解:

Orders类:

package com.dragon.spring5.bean;
public class Orders {
    private String oname;
    public Orders() {
        System.out.println("第一步 执行无参数构造创建bean实例");
    }
    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二步 调用set方法设置属性值");
    }
    public void initMethod(){
        System.out.println("第三步 执行初始化方法");
    }
    public void destoryMethod(){
        System.out.println("第五步 bean销毁的方法");
    }
}

后置处理器:

package com.dragon.spring5.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行的方法");
        return bean;
    }
}

测试:

package com.dragon.spring5.testDemo;
import com.dragon.spring5.bean.Orders;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test3 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean6.xml");
        Orders orders=context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建beam实例对象");
        System.out.println(orders);
        context.close();
    }
}

spring配置文件:

</bean>
<!--        后置处理器-->
        <bean id="myBeanPost" class="com.dragon.spring5.bean.MyBeanPost"></bean>

4.xml自动配置属性值

bean标签属性autowire两个常用值:

(1)byName:根据属性名称注入,注入值bean的id值和类属性名称一样

(2)byType:根据属性类型注入

spring配置文件:

(Emp类中有dept属性)

<bean id="emp" class="com.dragon.spring5.autowrite.Emp">
                <property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.dragon.spring5.autowrite.Dept"></bean>

正常情况下属性值需要用property标签注入。

而用autowire,可以自动注入

<bean id="emp" class="com.dragon.spring5.autowrite.Emp" autowire="byName"></bean>
        <bean id="dept" class="com.dragon.spring5.autowrite.Dept"></bean>

5.外部属性文件操作bean

这里用连接数据库举例:

在resource文件夹内jdbc属性文件(jdbc.properties)

pro.driverClass=com.mysql.jdbc.Driver
pro.url=jdbc:mysql://localhost:3306/?(这个根据自己数据库配置)
pro.username=root
pro.password=root

spring配置文件(注意context配置,这里使用的< context:property-placeholder/ >标签引入属性文件,其中classpath就是配置属性文件的全称):

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                <property name="driverClassName" value="${pro.driverClass}"></property>
                <property name="url" value="${pro.url}"></property>
                <property name="username" value="${pro.username}"></property>
                <property name="password" value="${pro.password}"></property>
        </bean>
</beans>

四、注解实现bean管理

1.基于注解创建对象

spring提供四种创建对象的注解(下面四个注解说的一般使用在哪层是约定俗成的,其实效果都一样,都可以混用):

  • @Component
  • @Service:一般用于业务逻辑或Service层
  • @Controller:一般用于web层
  • @ Repository:一般用于Dao层
    步骤:
    (1)引入依赖(开头已告知所有maven依赖库)
    (2)开启组件扫描:扫描base-package包下所有有注解的类并为其创建对象
<context:component-scan base-package="com.dragon.spring5_1"></context:component-scan>

代表扫描com.dragon.spring5_1下的所有文件,找寻有注解的文件,然后创建实例。

(2)创建类并在类上创建对象注解

@Service(value = "userService")
public class UserService {
    public void add(){
        System.out.println("service add.......");
    }
}

测试:

ApplicationContext context=new ClassPathXmlApplicationContext("bean9.xml");
        UserService userService=context.getBean("userService",UserService.class);
        System.out.println(userService);
        userService.add();

2.组件扫描细节

还有两种用法:

设置不扫描的注解
      <context:component-scan base-package="com.dragon.spring5_1">
                <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
        </context:component-scan>
    设置扫描的注解
        <context:component-scan base-package="com.dragon.spring5_1" use-default-filters="false">
                <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
        </context:component-scan>

3.基于注解进行属性注入

  • @Autowired:根据属性类型自动装配
  • @Qualifier:根据属性名称自动装配,需要和@Autowired一起使用
    当遇到一个接口有很多实现类时,只通过@Autowire是无法完成自动装配的,所以需要再使用@Qualifier通过名称来锁定某个类
  • @Resource:可以根据类型注入,也可以根据名称注入(不常用)
  • @Value:注入属性值
    实例:
    UserDao、UserDaoImpl、UserService类:
package com.dragon.spring5_1.dao;
import org.springframework.stereotype.Repository;
public interface UserDao {
    public void add();
}
==================================================
package com.dragon.spring5_1.dao;
import org.springframework.stereotype.Repository;
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("dao add......");
    }
}
=========================================================
package com.dragon.spring5_1.service;
import com.dragon.spring5_1.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service(value = "userService")
public class UserService {
    @Value(value = "abc")
    private String name;
    @Autowired
    @Qualifier(value ="userDaoImpl1")
    private UserDao userDao;
    public void add(){
        System.out.println("service add......."+name);
        userDao.add();
    }
}

spring配置文件:

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">
        <context:component-scan base-package="com.dragon.spring5_1"></context:component-scan>
</beans>

测试:

ApplicationContext context=new ClassPathXmlApplicationContext("bean9.xml");
        UserService userService=context.getBean("userService",UserService.class);
        System.out.println(userService);
        userService.add();

五、完全注解开发

上面讲诉后,完全注解开发应该是最简洁的。来个实例看一看。

这时要引入配置类来代替spring配置文件,来实现组件扫描不用xml配置,进而实现完全注解开发。

配置类:

package com.dragon.spring5_1.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration//配置类
@ComponentScan(basePackages = {"com.dragon.spring5_1"})//配置扫描的文件
public class SpringConfig {
}

测试(UserDao、UserDaoImpl、UserService还是上面基于注解属性注入例子的):

package com.dragon.spring5_1.testDemo;
import com.dragon.spring5_1.config.SpringConfig;
import com.dragon.spring5_1.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class test2 {
    public static void main(String[] args) {
      //注意new的对象变了,变成了AnnotationConfigApplicationContext
        ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService=context.getBean("userService", UserService.class);
        System.out.println(userService);  
        userService.add();
    }
}

总结

以上就是Spring的IOC讲解。

相关文章
|
10月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
10月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
810 2
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
328 1
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
438 18
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
消息中间件 设计模式 缓存
Spring相关文章汇总篇【Spring,SpringBoot,SpringCloud等】
因为Spring框架包含的组件比较多,写的博客内容也比较多,虽然有分专栏但是依然不方便查找,所以专门用一篇文章来记录相关文章,会不定期更新。
Spring相关文章汇总篇【Spring,SpringBoot,SpringCloud等】
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1474 0
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
1412 0
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
609 0
|
10月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
668 4

热门文章

最新文章