【Spring6】IoC容器之基于XML管理Bean
创始人
2024-05-29 06:28:55
0

3、容器:IoC

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。

Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。

IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。

3.1、IoC容器

3.1.1、控制反转(IoC)

  • 控制反转是一种思想。

  • 控制反转是为了降低程序耦合度,提高程序扩展力。

  • 控制反转,反转的是什么?

    • 将对象的创建权利交出去,交给第三方容器负责。
    • 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
  • 控制反转这种思想如何实现呢?

    • DI(Dependency Injection):依赖注入

3.1.2、依赖注入

DI(Dependency Injection):依赖注入,依赖注入实现了控制反转的思想。

依赖注入:

  • 指Spring创建对象的过程中,将对象依赖属性通过配置进行注入

依赖注入常见的实现方式包括两种:

  • 第一种:set注入
  • 第二种:构造注入

所以结论是:IOC 就是一种控制反转的思想, 而 DI 是对IoC的一种具体实现。

Bean管理说的是:Bean对象的创建,以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)。

3.1.3、IoC容器在Spring的实现

Spring 的 IoC 容器就是 IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前,首先需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式:

①BeanFactory

这是 IoC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。

②ApplicationContext

BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。

③ApplicationContext的主要实现类

在这里插入图片描述

类型名简介
ClassPathXmlApplicationContext通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象
FileSystemXmlApplicationContext通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象
ConfigurableApplicationContextApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的能力。
WebApplicationContext专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。

3.2、基于XML管理Bean

3.2.1、搭建子模块spring6-ioc-xml

①搭建模块

搭建方式如:spring-first

②引入配置文件

引入spring-first模块配置文件:beans.xml、log4j2.xml

③添加依赖

org.springframeworkspring-context6.0.3org.junit.jupiterjunit-jupiter-api5.3.1org.apache.logging.log4jlog4j-core2.19.0org.apache.logging.log4jlog4j-slf4j2-impl2.19.0

④引入java类

引入spring-first模块java及test目录下实体类

package com.atguigu.spring6.bean;public class HelloWorld {public HelloWorld() {System.out.println("无参数构造方法执行");}public void sayHello(){System.out.println("helloworld");}
}
package com.atguigu.spring6.bean;import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class HelloWorldTest {private Logger logger = LoggerFactory.getLogger(HelloWorldTest.class);@Testpublic void testHelloWorld(){}
}

3.2.2、实验一:获取bean

配置bean


①方式一:根据id获取

由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。

@Test
public void testHelloWorld(){ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");HelloWorld helloworld = (HelloWorld) ac.getBean("helloWorld");helloworld.sayHello();
}
②方式二:根据类型获取
@Test
public void testHelloWorld1(){ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");HelloWorld bean = ac.getBean(HelloWorld.class);bean.sayHello();
}
③方式三:根据id和类型
@Test
public void testHelloWorld2(){ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");HelloWorld bean = ac.getBean("helloworld", HelloWorld.class);bean.sayHello();
}
④注意的地方

当根据类型获取bean时,要求IOC容器中指定类型的bean有且只能有一个

当IOC容器中一共配置了两个:



根据类型获取时会抛出异常:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.atguigu.spring6.bean.HelloWorld’ available: expected single matching bean but found 2: helloworldOne,helloworldTwo

此时只能根据id或者id加类型获取

⑤扩展知识

如果组件类实现了接口,根据接口类型可以获取 bean 吗?

可以,前提是bean唯一

如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?

不行,因为bean不唯一

结论

根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类型』的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

java中,instanceof运算符用于判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。也就是说:用instanceof关键字做判断时, instanceof 操作符的左右操作必须有继承或实现关系

3.2.3、实验二:依赖注入之setter注入

①创建学生类Student

package com.atguigu.spring6.bean;public class Student {private Integer id;private String name;private Integer age;private String sex;public Student() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +'}';}}

②配置bean时为属性赋值

spring-di.xml



③测试

@Test
public void testDIBySet(){ApplicationContext ac = new ClassPathXmlApplicationContext("spring-di.xml");Student studentOne = ac.getBean("studentOne", Student.class);System.out.println(studentOne);
}

3.2.4、实验三:依赖注入之构造器注入

①在Student类中添加有参构造

public Student(Integer id, String name, Integer age, String sex) {this.id = id;this.name = name;this.age = age;this.sex = sex;
}

②配置bean

spring-di.xml



注意:

constructor-arg标签还有两个属性可以进一步描述构造器参数:

  • index属性:指定参数所在位置的索引(从0开始)
  • name属性:指定参数名

③测试

@Test
public void testDIByConstructor(){ApplicationContext ac = new ClassPathXmlApplicationContext("spring-di.xml");Student studentOne = ac.getBean("studentTwo", Student.class);System.out.println(studentOne);
}

通过构造器注入时只会执行有参构造器

3.2.5、实验四:特殊值处理

①字面量赋值

什么是字面量?

int a = 10;

声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a的时候,我们实际上拿到的值是10。

而如果a是带引号的:‘a’,那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。所以字面量没有引申含义,就是我们看到的这个数据本身。



②null值


注意:


以上写法,为name所赋的值是字符串null

③xml实体



④CDATA节


3.2.6、实验五:为对象类型属性赋值

①创建班级类Clazz

package com.atguigu.spring6.beanpublic class Clazz {private Integer clazzId;private String clazzName;public Integer getClazzId() {return clazzId;}public void setClazzId(Integer clazzId) {this.clazzId = clazzId;}public String getClazzName() {return clazzName;}public void setClazzName(String clazzName) {this.clazzName = clazzName;}@Overridepublic String toString() {return "Clazz{" +"clazzId=" + clazzId +", clazzName='" + clazzName + '\'' +'}';}public Clazz() {}public Clazz(Integer clazzId, String clazzName) {this.clazzId = clazzId;this.clazzName = clazzName;}
}

②修改Student类

在Student类中添加以下代码:

private Clazz clazz;public Clazz getClazz() {return clazz;
}public void setClazz(Clazz clazz) {this.clazz = clazz;
}
方式一:引用外部bean

配置Clazz类型的bean:



为Student中的clazz属性赋值:



错误演示:



如果错把ref属性写成了value属性,会抛出异常: Caused by: java.lang.IllegalStateException: Cannot convert value of type ‘java.lang.String’ to required type ‘com.atguigu.spring6.bean.Clazz’ for property ‘clazz’: no matching editors or conversion strategy found

意思是不能把String类型转换成我们要的Clazz类型,说明我们使用value属性时,Spring只把这个属性看做一个普通的字符串,不会认为这是一个bean的id,更不会根据它去找到bean来赋值

方式二:内部bean


方式三:级联属性赋值


3.2.7、实验六:为数组类型属性赋值

①修改Student类

在Student类中添加以下代码:

private String[] hobbies;public String[] getHobbies() {return hobbies;
}public void setHobbies(String[] hobbies) {this.hobbies = hobbies;
}

②配置bean

抽烟喝酒烫头

3.2.8、实验七:为集合类型属性赋值

①为List集合类型属性赋值

在Clazz类中添加以下代码:

private List students;public List getStudents() {return students;
}public void setStudents(List students) {this.students = students;
}

配置bean:



若为Set集合类型属性赋值,只需要将其中的list标签改为set标签即可

②为Map集合类型属性赋值

创建教师类Teacher:

package com.atguigu.spring6.bean;
public class Teacher {private Integer teacherId;private String teacherName;public Integer getTeacherId() {return teacherId;}public void setTeacherId(Integer teacherId) {this.teacherId = teacherId;}public String getTeacherName() {return teacherName;}public void setTeacherName(String teacherName) {this.teacherName = teacherName;}public Teacher(Integer teacherId, String teacherName) {this.teacherId = teacherId;this.teacherName = teacherName;}public Teacher() {}@Overridepublic String toString() {return "Teacher{" +"teacherId=" + teacherId +", teacherName='" + teacherName + '\'' +'}';}
}

在Student类中添加以下代码:

private Map teacherMap;public Map getTeacherMap() {return teacherMap;
}public void setTeacherMap(Map teacherMap) {this.teacherMap = teacherMap;
}

配置bean:



抽烟喝酒烫头1001010086

③引用集合类型的bean




1001010086



抽烟喝酒烫头

使用util:list、util:map标签必须引入相应的命名空间



3.2.9、实验八:p命名空间

引入p命名空间



引入p命名空间后,可以通过以下方式为bean的各个属性赋值


3.2.10、实验九:引入外部属性文件

①加入依赖

 
mysqlmysql-connector-java8.0.30

com.alibabadruid1.2.15

②创建外部属性文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQVUwjNN-1677994650279)(images/spring6/img010.png)]

jdbc.user=root
jdbc.password=atguigu
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver

③引入属性文件

引入context 名称空间





注意:在使用 context:property-placeholder 元素加载外包配置文件功能前,首先需要在 XML 配置的一级标签 中添加 context 相关的约束。

④配置bean



⑤测试

@Test
public void testDataSource() throws SQLException {ApplicationContext ac = new ClassPathXmlApplicationContext("spring-datasource.xml");DataSource dataSource = ac.getBean(DataSource.class);Connection connection = dataSource.getConnection();System.out.println(connection);
}

3.2.11、实验十:bean的作用域

①概念

在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围,各取值含义参加下表:

取值含义创建对象的时机
singleton(默认)在IOC容器中,这个bean的对象始终为单实例IOC容器初始化时
prototype这个bean在IOC容器中有多个实例获取bean时

如果是在WebApplicationContext环境下还会有另外几个作用域(但不常用):

取值含义
request在一个请求范围内有效
session在一个会话范围内有效

②创建类User

package com.atguigu.spring6.bean;
public class User {private Integer id;private String username;private String password;private Integer age;public User() {}public User(Integer id, String username, String password, Integer age) {this.id = id;this.username = username;this.password = password;this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", age=" + age +'}';}
}

③配置bean




④测试

@Test
public void testBeanScope(){ApplicationContext ac = new ClassPathXmlApplicationContext("spring-scope.xml");User user1 = ac.getBean(User.class);User user2 = ac.getBean(User.class);System.out.println(user1==user2);
}

通过测试可以看出,scope="prototype"得到的两个bean不是同一个bean

3.2.12、实验十一:bean生命周期

①具体的生命周期过程

  • bean对象创建(调用无参构造器)

  • 给bean对象设置属性

  • bean的前置处理器(初始化之前)

  • bean对象初始化(需在配置bean时指定初始化方法)

  • bean的后置处理器(初始化之后)

  • bean对象就绪可以使用

  • bean对象销毁(需在配置bean时指定销毁方法)

  • IOC容器关闭

②修改类User

public class User {private Integer id;private String username;private String password;private Integer age;public User() {System.out.println("生命周期:1、创建对象");}public User(Integer id, String username, String password, Integer age) {this.id = id;this.username = username;this.password = password;this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {System.out.println("生命周期:2、依赖注入");this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public void initMethod(){System.out.println("生命周期:3、初始化");}public void destroyMethod(){System.out.println("生命周期:5、销毁");}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", age=" + age +'}';}
}

注意其中的initMethod()和destroyMethod(),可以通过配置bean指定为初始化和销毁的方法

③配置bean





④测试

@Test
public void testLife(){ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-lifecycle.xml");User bean = ac.getBean(User.class);System.out.println("生命周期:4、通过IOC容器获取bean并使用");ac.close();
}

⑤bean的后置处理器

bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行

创建bean的后置处理器:

package com.atguigu.spring6.process;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("☆☆☆" + beanName + " = " + bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("★★★" + beanName + " = " + bean);return bean;}
}

在IOC容器中配置后置处理器:





注意此处如果是这样子写,就只会执行有参构造器,不会执行无参构造器

3.2.13、实验十二:FactoryBean

①简介

FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。

将来我们整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的。

/** Copyright 2002-2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package org.springframework.beans.factory;import org.springframework.lang.Nullable;/*** Interface to be implemented by objects used within a {@link BeanFactory} which* are themselves factories for individual objects. If a bean implements this* interface, it is used as a factory for an object to expose, not directly as a* bean instance that will be exposed itself.** 

NB: A bean that implements this interface cannot be used as a normal bean.* A FactoryBean is defined in a bean style, but the object exposed for bean* references ({@link #getObject()}) is always the object that it creates.**

FactoryBeans can support singletons and prototypes, and can either create* objects lazily on demand or eagerly on startup. The {@link SmartFactoryBean}* interface allows for exposing more fine-grained behavioral metadata.**

This interface is heavily used within the framework itself, for example for* the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or the* {@link org.springframework.jndi.JndiObjectFactoryBean}. It can be used for* custom components as well; however, this is only common for infrastructure code.**

{@code FactoryBean} is a programmatic contract. Implementations are not* supposed to rely on annotation-driven injection or other reflective facilities.* {@link #getObjectType()} {@link #getObject()} invocations may arrive early in the* bootstrap process, even ahead of any post-processor setup. If you need access to* other beans, implement {@link BeanFactoryAware} and obtain them programmatically.**

The container is only responsible for managing the lifecycle of the FactoryBean* instance, not the lifecycle of the objects created by the FactoryBean. Therefore,* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()}* will not be called automatically. Instead, a FactoryBean should implement* {@link DisposableBean} and delegate any such close call to the underlying object.**

Finally, FactoryBean objects participate in the containing BeanFactory's* synchronization of bean creation. There is usually no need for internal* synchronization other than for purposes of lazy initialization within the* FactoryBean itself (or the like).** @author Rod Johnson* @author Juergen Hoeller* @since 08.03.2003* @param the bean type* @see org.springframework.beans.factory.BeanFactory* @see org.springframework.aop.framework.ProxyFactoryBean* @see org.springframework.jndi.JndiObjectFactoryBean*/ public interface FactoryBean {/*** The name of an attribute that can be* {@link org.springframework.core.AttributeAccessor#setAttribute set} on a* {@link org.springframework.beans.factory.config.BeanDefinition} so that* factory beans can signal their object type when it can't be deduced from* the factory bean class.* @since 5.2*/String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";/*** Return an instance (possibly shared or independent) of the object* managed by this factory.*

As with a {@link BeanFactory}, this allows support for both the* Singleton and Prototype design pattern.*

If this FactoryBean is not fully initialized yet at the time of* the call (for example because it is involved in a circular reference),* throw a corresponding {@link FactoryBeanNotInitializedException}.*

As of Spring 2.0, FactoryBeans are allowed to return {@code null}* objects. The factory will consider this as normal value to be used; it* will not throw a FactoryBeanNotInitializedException in this case anymore.* FactoryBean implementations are encouraged to throw* FactoryBeanNotInitializedException themselves now, as appropriate.* @return an instance of the bean (can be {@code null})* @throws Exception in case of creation errors* @see FactoryBeanNotInitializedException*/@NullableT getObject() throws Exception;/*** Return the type of object that this FactoryBean creates,* or {@code null} if not known in advance.*

This allows one to check for specific types of beans without* instantiating objects, for example on autowiring.*

In the case of implementations that are creating a singleton object,* this method should try to avoid singleton creation as far as possible;* it should rather estimate the type in advance.* For prototypes, returning a meaningful type here is advisable too.*

This method can be called before this FactoryBean has* been fully initialized. It must not rely on state created during* initialization; of course, it can still use such state if available.*

NOTE: Autowiring will simply ignore FactoryBeans that return* {@code null} here. Therefore it is highly recommended to implement* this method properly, using the current state of the FactoryBean.* @return the type of object that this FactoryBean creates,* or {@code null} if not known at the time of the call* @see ListableBeanFactory#getBeansOfType*/@NullableClass getObjectType();/*** Is the object managed by this factory a singleton? That is,* will {@link #getObject()} always return the same object* (a reference that can be cached)?*

NOTE: If a FactoryBean indicates to hold a singleton object,* the object returned from {@code getObject()} might get cached* by the owning BeanFactory. Hence, do not return {@code true}* unless the FactoryBean always exposes the same reference.*

The singleton status of the FactoryBean itself will generally* be provided by the owning BeanFactory; usually, it has to be* defined as singleton there.*

NOTE: This method returning {@code false} does not* necessarily indicate that returned objects are independent instances.* An implementation of the extended {@link SmartFactoryBean} interface* may explicitly indicate independent instances through its* {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}* implementations which do not implement this extended interface are* simply assumed to always return independent instances if the* {@code isSingleton()} implementation returns {@code false}.*

The default implementation returns {@code true}, since a* {@code FactoryBean} typically manages a singleton instance.* @return whether the exposed object is a singleton* @see #getObject()* @see SmartFactoryBean#isPrototype()*/default boolean isSingleton() {return true;} }

②创建类UserFactoryBean

package com.atguigu.spring6.bean;
public class UserFactoryBean implements FactoryBean {@Overridepublic User getObject() throws Exception {return new User();}@Overridepublic Class getObjectType() {return User.class;}
}

③配置bean


④测试

@Test
public void testUserFactoryBean(){//获取IOC容器ApplicationContext ac = new ClassPathXmlApplicationContext("spring-factorybean.xml");User user = (User) ac.getBean("user");System.out.println(user);
}

3.2.14、实验十三:基于xml自动装配

自动装配:

根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类型属性赋值

①场景模拟

创建类UserController

package com.atguigu.spring6.autowire.controller
public class UserController {private UserService userService;public void setUserService(UserService userService) {this.userService = userService;}public void saveUser(){userService.saveUser();}}

创建接口UserService

package com.atguigu.spring6.autowire.service
public interface UserService {void saveUser();}

创建类UserServiceImpl实现接口UserService

package com.atguigu.spring6.autowire.service.impl
public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveUser() {userDao.saveUser();}}

创建接口UserDao

package com.atguigu.spring6.autowire.dao
public interface UserDao {void saveUser();}

创建类UserDaoImpl实现接口UserDao

package com.atguigu.spring6.autowire.dao.impl
public class UserDaoImpl implements UserDao {@Overridepublic void saveUser() {System.out.println("保存成功");}}

②配置bean

使用bean标签的autowire属性设置自动装配效果

自动装配方式:byType

byType:根据类型匹配IOC容器中的某个兼容类型的bean,为属性自动赋值

若在IOC中,没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,即值为默认值null

若在IOC中,有多个兼容类型的bean能够为属性赋值,则抛出异常NoUniqueBeanDefinitionException


自动装配方式:byName

byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值


③测试

@Test
public void testAutoWireByXML(){ApplicationContext ac = new ClassPathXmlApplicationContext("autowire-xml.xml");UserController userController = ac.getBean(UserController.class);userController.saveUser();
}

本文章参考B站 尚硅谷Spring零基础视频教程,2023版spring6入门到精通,仅供个人学习使用,部分内容为本人自己见解,与尚硅谷无关。

相关内容

热门资讯

谢灵运山水诗对李白的创作影响 谢灵运山水诗对李白的创作影响  东晋诗人谢灵运,作为中国古典诗歌山水诗派的开创者之一,在晋宋之交,为...
永远的守巢人诗歌_歌颂老师   又到毕业季,又有不少的孩子即将离开那个呵护了他们三年的小乐园,开始第一次学会和朋友们说再见。下面...
小学生抗疫情诗歌 小学生抗疫情诗歌  无论是身处学校还是步入社会,大家一定没少看到经典的诗歌吧,诗歌语言言简义丰,具有...
忘不掉你的承诺诗歌 忘不掉你的承诺诗歌  当自己心中的那个他走了之后,  让人最难忘记的是“记忆”  因为,  那一段记...
你是我心中永远的痛爱情诗歌 你是我心中永远的痛爱情诗歌  你我曾经  肩并肩、手牵着手徜徉在花丛中  一起观赏人间的四季美景  ...
爱情的诗歌 有关爱情的诗歌  在平时的学习、工作或生活中,大家都看到过许多经典的诗歌吧,诗歌是按照一定的音节、韵...
适合过年听的欢快的歌曲 适合过年听的欢快的歌曲  过年期间都是一个很喜庆的时间,很多店铺商场都开始放一些音乐去吸引客人或者说...
醉生梦死诗歌 醉生梦死诗歌醉生梦死诗歌1  禁果的滋味  苦涩而甜蜜  人生第一次爱过  不知不觉已成悲伤之人  ...
《雨说》诗歌 《雨说》诗歌  在平日的学习、工作和生活里,许多人都接触过一些比较经典的诗歌吧,诗歌饱含丰富的感情和...
蜗行诗歌 蜗行诗歌  在生活、工作和学习中,大家总免不了要接触或使用诗歌吧,诗歌在形式上,不是以句子为单位,而...
国庆节的诗歌 关于国庆节的诗歌再过几天就是十月一号的国庆节了,自古以来,吟诗作赋是文人对节日的表达感情方式之一。下...
歌颂伟大的母亲党成立100周... 弹指间,2021年来了,我们伟大的母亲中国共产党也走过了100年,那歌颂伟大的母亲中国共产党成立10...
欧阳修的醉翁亭记 欧阳修的醉翁亭记  《醉翁亭记》不仅是一首千古传诵的游记,散文中饶有诗情画意,别具清丽格调,是一篇具...
关于中秋节的诗歌大全 关于中秋节的诗歌大全,小编为你推荐下文,希望可以帮助到你。欢迎你的阅读参考。1、《中秋》唐·李朴皓魄...
《落日怅望》诗歌鉴赏 《落日怅望》诗歌鉴赏  落日怅望  马戴  孤云与归鸟,千里片时间。  念我何留滞,辞家久未还。  ...
小学画课文原文 小学画课文原文  画为初唐诗人王维所做的一首五言绝句。下面就随小编一起去阅读小学画古诗原文,相信能带...
诗歌赏析:《六月的雨》 诗歌赏析:《六月的雨》  在平日的学习、工作和生活里,大家都经常接触到诗歌吧,诗歌是一种抒情言志的文...
泰山嵯峨夏云在,疑是白波涨东... “泰山嵯峨夏云在,疑是白波涨东海。”出处 出自 唐代 李白 的《早秋单父南楼酬窦公衡》“泰山嵯峨夏云...
彻夜难眠的经典诗句 彻夜难眠的经典诗句  在平凡的学习、工作、生活中,大家都经常接触到诗句吧,诗句具有语言节奏鲜明的特点...
描写长江雄阔的诗句 描写长江雄阔的诗句  白日依山尽,黄河入海流。王之涣《登鹳雀楼》  春别曲【唐】张籍长江春水绿堪染,...