的C友,都能快速入门spring

Posted Java架构-大仙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了的C友,都能快速入门spring相关的知识,希望对你有一定的参考价值。

Spring快速入门

1.spring

Spring 框架可以说是Java 世界最为成功的框架,在企业实际应用中,大部分的企业架构都基于Spring 框架。它的成功来自于理念,而不是技术,它最为核心的理念是IoC (控制反转)和AOP (面向切面编程),其中IoC 是Spring的基础,而AOP 则是其重要的功能,最为典型的当属数据库事务的使用。

Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。

1.1.优点

  1. 方便解耦,简化开发

    Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。

  2. AOP编程的支持

    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。

  3. 声明式事务的支持

    只需要通过配置就可以完成对事务的管理,而无需手动编程。

  4. 方便程序的测试

    Spring对Junit4支持,可以通过注解方便的测试Spring程序。

  5. 方便集成各种优秀框架

    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。

  6. 降低JavaEE API的使用难度

    Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

1.2.缺点

  1. Spring明明一个很轻量级的框架,却给人感觉大而全
  2. Spring依赖反射,反射影响性能
  3. 使用门槛升高,入门Spring需要较长时间

1.3.Spring框架的组成结构图

Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被分别整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)和设备支持(Instrmentation) 、数据访问与集成(Data Access/Integeration) 、 Web、 消息(Messaging) 、 Test等 6 个模块中。 以下是 Spring 5 的模块结构图:

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

1.3.1.核心容器

Spring的核心容器是其他模块建立的基础,有spring-core、spring-beans、spring-context、spring-context-support和spring-expression(Spring表达式语言)等模块组成。

spring-core 模块:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。

spring-beans 模块:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。

spring-context 模块:建立在Core和Beans模块的基础之上,提供一个框架式的对象访问方式,是访问定义和配置的任何对象的媒介。ApplicationContext接口是Context模块的焦点。

spring-context-support 模块:支持整合第三方库到Spring应用程序上下文,特别是用于高速缓存(EhCache、JCache)和任务调度(CommonJ、Quartz)的支持。

Spring-expression 模块:提供了强大的表达式语言去支持运行时查询和操作对象图。这是对JSP2.1规范中规定的统一表达式语言(Unified EL)的扩展。该语言支持设置和获取属性值、属性分配、方法调用、访问数组、集合和索引器的内容、逻辑和算术运算、变量命名以及从Spring的IOC容器中以名称检索对象。它还支持列表投影、选择以及常用的列表聚合。

1.3.2.AOP 和设备支持

由spring-aop、 spring-aspects 和 spring-instrument等 3 个模块组成。

spring-aop 模块:是 Spring 的另一个核心模块,提供了一个符合 AOP 要求的面向切面的编程实现。 作为继 OOP(面向对象编程) 后, 对程序员影响最大的编程思想之一, AOP 极大地开拓了人们对于编程的思路。 在 Spring 中, 以动态代理技术为基础,允许定义方法拦截器和切入点,将代码按照功能进行分离,以便干净地解耦。

spring-aspects 模块:提供了与AspectJ的集成功能,AspectJ是一个功能强大且成熟的AOP框架。

spring-instrument 模块:是 AOP 的一个支援模块, 提供了类植入(Instrumentation)支持和类加载器的实现,可以在特定的应用服务器中使用。主要作用是在 JVM 启用时, 生成一个代理类, 程序员通过代理类在运行时修改类的字节, 从而改变一个类的功能, 实现 AOP 的功能。

1.3.3.数据访问与集成

由 spring-jdbc、spring-orm、spring-oxm、spring-jms 和 spring-tx 等 5 个模块组成。

spring-jdbc 模块:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。主要是提供 JDBC 模板方式、 关系数据库对象化方式、 SimpleJdbc 方式、 事务管理来简化 JDBC 编程, 主要实现类是 JdbcTemplate、 SimpleJdbcTemplate 以及 NamedParameterJdbcTemplate。

spring-orm 模块:是 ORM 框架支持模块, 主要集成 Hibernate, Java Persistence API (JPA) 和Java Data Objects (JDO) 用于资源管理、 数据访问对象(DAO)的实现和事务策略。

spring-oxm 模块:主要提供一个抽象层以支撑 OXM(OXM 是 Object-to-XML-Mapping 的缩写, 它是一个 O/M-mapper, 将 java 对象映射成 XML 数据, 或者将 XML 数据映射成 java 对象) , 例如: JAXB,Castor,XMLBeans,JiBX 和 XStream 等。

spring-jms模块(Java Messaging Service):指Java消息传递服务,包含用于生产和使用消息的功能。自Spring4.1以后,提供了与spring-messaging模块的集成。

spring-tx 模块:事务模块,支持用于实现特殊接口和所有POJO(普通Java对象)类的编程和声明式事务管理。

1.3.4.Web

由spring-websocket、spring-webmvc、spring-web、portlet和spring-webflux模块等 5 个模块组成。

spring-websocket 模块:Spring4.0以后新增的模块,实现双工异步通讯协议,实现了WebSocket和SocketJS,提供Socket通信和web端的推送功能。

spring-webmvc 模块:也称为Web-Servlet模块,包含用于web应用程序的Spring MVC和REST Web Services实现。Spring MVC框架提供了领域模型代码和Web表单之间的清晰分离,并与Spring Framework的所有其他功能集成。

spring-web 模块:提供了基本的Web开发集成功能,包括使用Servlet监听器初始化一个IOC容器以及Web应用上下文,自动载入WebApplicationContext特性的类,Struts集成类、文件上传的支持类、Filter类和大量辅助工具类。

portlet 模块:实现web模块功能的聚合,类似于Servlet模块的功能,提供了Portlet环境下的MVC实现。

spring-webflux 模块:是一个新的非堵塞函数式 Reactive Web 框架, 可以用来建立异步的, 非阻塞,事件驱动的服务, 并且扩展性非常好。

1.3.5.消息(Messaging)

即 spring-messaging 模块。

spring-messaging 是从 Spring4 开始新加入的一个模块, 该模块提供了对消息传递体系结构和协议的支持。

1.3.6.Test

即 spring-test 模块。

spring-test 模块主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。

2.Spring核心ioc

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。就是不实例化了。先注入。

谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取

●**为何是反转,哪些方面反转了:**有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

ps:控制反转是目标,依赖注入是手段。

2.1.ioc容器

IoC 容器是 Spring 的核心,也可以称为 Spring 容器。Spring 通过 IoC 容器来管理对象的实例化和初始化,以及对象从创建到销毁的整个生命周期。

Spring 中使用的对象都由 IoC 容器管理,不需要我们手动使用 new 运算符创建对象。由 IoC 容器管理的对象称为 Spring Bean,Spring Bean 就是 Java 对象,和使用 new 运算符创建的对象没有区别。

Spring 通过读取 XML 或 Java 注解中的信息来获取哪些对象需要实例化。

Spring 提供 2 种不同类型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器

2.1.BeanFactory 容器

BeanFactory 是最简单的容器,由 org.springframework.beans.factory.BeanFactory 接口定义,采用懒加载(lazy-load),所以容器启动比较快。BeanFactory 提供了容器最基本的功能。

为了能够兼容 Spring 集成的第三方框架(如 BeanFactoryAware、InitializingBean、DisposableBean),所以目前仍然保留了该接口。

简单来说,BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。

BeanFactory 接口有多个实现类,最常见的是 org.springframework.beans.factory.xml.XmlBeanFactory。使用 BeanFactory 需要创建 XmlBeanFactory 类的实例,通过 XmlBeanFactory 类的构造函数来传递 Resource 对象。如下所示。

Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);  

2.1.2. ApplicationContext 容器

ApplicationContext 继承了 BeanFactory 接口,由 org.springframework.context.ApplicationContext 接口定义,对象在启动容器时加载。ApplicationContext 在 BeanFactory 的基础上增加了很多企业级功能,例如 AOP、国际化、事件支持等。

ApplicationContext 接口有两个常用的实现类,具体如下。

2.1.2.1.ClassPathXmlApplicationContext

该类从类路径 ClassPath 中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);

在上述代码中,configLocation 参数用于指定 Spring 配置文件的名称和位置,如 Beans.xml。

2.1.2.2.FileSystemXmlApplicationContext

该类从指定的文件系统路径中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

它与 ClassPathXmlApplicationContext 的区别是:在读取 Spring 的配置文件时,FileSystemXmlApplicationContext 不会从类路径中读取配置文件,而是通过参数指定配置文件的位置。即 FileSystemXmlApplicationContext 可以获取类路径之外的资源,如“F:/workspaces/Beans.xml”。

2.1.2.3.AnnotationConfigApplicationContext

读取用注解创建容器

通常在 Java 项目中,会采用 ClassPathXmlApplicationContext 类实例化 ApplicationContext 容器的方式,而在 Web 项目中,ApplicationContext 容器的实例化工作会交由 Web 服务器完成。Web 服务器实例化 ApplicationContext 容器通常使用基于 ContextLoaderListener 实现的方式,它只需要在 web.xml 中添加如下代码:

<!--指定Spring配置文件的位置,有多个配置文件时,以逗号分隔-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!--spring将加载spring目录下的applicationContext.xml文件-->
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

需要注意的是,BeanFactory 和 ApplicationContext 都是通过 XML 配置文件加载 Bean 的。

二者的主要区别在于,如果 Bean 的某一个属性没有注入,使用 BeanFacotry 加载后,第一次调用 getBean() 方法时会抛出异常,而 ApplicationContext 则会在初始化时自检,这样有利于检查所依赖的属性是否注入。

因此,在实际开发中,通常都选择使用 ApplicationContext,只有在系统资源较少时,才考虑使用 BeanFactory。

2.2.使用ioc容器

2.2.1.beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="com.wyl.pojo.User">
        <property name="name" value="王延领"/>
    </bean>
</beans>

2.2.2.pojo.User

public class User  
    private String name; 
    public User() 
        System.out.println("user无参构造方法");
     
    public void setName(String name) 
        this.name = name;
     
    public void show()
        System.out.println("name="+ name );
    


2.2.2.test

@Test
public void test()
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //在执行getBean的时候, user已经创建好了 , 通过无参构造
    User user = (User) context.getBean("user");
    //调用对象的方法 .
    user.show();


2.3.bean

2.3.1.定义

由 Spring IoC 容器管理的对象称为 Bean,Bean 根据 Spring 配置文件中的信息创建。可以把 Spring IoC 容器看作是一个大工厂,Bean 相当于工厂的产品,如果希望这个大工厂生产和管理 Bean,则需要告诉容器需要哪些 Bean,以及需要哪种方式装配 Bean。

Spring 配置文件支持两种格式,即 XML 文件格式和 Properties 文件格式。

  • Properties 配置文件主要以 key-value 键值对的形式存在,只能赋值,不能进行其他操作,适用于简单的属性配置。

  • XML 配置文件是树形结构,相对于 Properties 文件来说更加灵活。XML 配置文件结构清晰,但是内容比较繁琐,适用于大型复杂的项目。

通常情况下,Spring 的配置文件使用 XML 格式。XML 配置文件的根元素是 ,该元素包含了多个子元素 。每一个 元素都定义了一个 Bean,并描述了该 Bean 如何被装配到 Spring 容器中。

2.3.2.创建

2.3.2.1 默认方式

无参

<!-- 1\\. 默认构造函数,如果类中没有默认构造函数则无法创建对象;bean标签中只有id和class就默认使用构造函数创建对象 -->
<bean id="userService" class="com.wyl.pojo.User"/>

有参

<!-- 第一种根据index参数下标设置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <!-- index指构造方法 , 下标从0开始 -->
    <constructor-arg index="0" value="wyl"/>
</bean>

<!-- 第二种根据参数名字设置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <!-- name指参数名 -->
    <constructor-arg name="name" value="wyl"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <constructor-arg type="java.lang.String" value="wyl"/>
</bean>

2.3.2.2 工厂类中的方法

<!-- 2\\. 使用工厂中的方法创建对象;工厂中有一个方法可以创建对象,先创建工厂对象,通过factory-bean指向工厂,使用factory-method方法获取对象 -->
<bean id="beanFactory" class="org.factory.BeanFactory"/>
<bean id="userService" factory-bean="beanFactory" factory-method="getUserService"/>

2.3.2.3 静态工厂中的静态方法

<!-- 3\\. 使用静态工厂中的静态方法创建对象 -->
<bean id="userService" class="org.factory.StaticBeanFactory" factory-method="getUserService"/>

2.3.2.配置

2.3.2.1.别名

<!--  别名 : 如果添加了别名,我们也可以使用别名获取到这个对象 -->
<alias name="User" alias="u1"></alias>

2.3.2.2.bean 别名

<!--
  bean标签常用属性:

id属性:起名称,id属性值名称任意命名,不能包含特殊符号
class属性:创建对象所在类的全路径
name属性:功能和id属性一样的,但是在name属性值里面可以包含特殊符号
scope属性
singleton:默认值,单例
prototype:多例
request:创建对象把对象放到request域里面
session:创建对象把对象放到session域里面
globalSession:创建对象把对象放到globalSession里面
  -->
<bean id="UserT" class="com.wyl.pojo.User" scope="singleton" name="u2 u21,u22;u23">
    <property name="name" value="123"/>
</bean>

2.3.2.2.import

团队的合作通过import来实现 .

<import resource="beans.xml"/>

能将多个人开发的不同的配置xml文件整合到applicationContext.xml文件中,并且能够合适的去重。

2.3.3.作用域

<bean id="..." class="..." scope="singleton"/>

Spring 容器在初始化一个 Bean 实例时,同时会指定该实例的作用域。Spring 5 支持以下 6 种作用域。

singleton

默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例,Bean 以单例的方式存在。

prototype

原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例。

request

每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。

session

同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。

application

同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。
类似于 singleton,不同的是,singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而同一个 Web 应用中可能会有多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。

websocket

websocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效
equest、session、application、websocket 和 global Session 作用域只能在 Web 环境下使用,如果使用 ClassPathXmlApplicationContext 加载这些作用域中的任意一个的 Bean,就会抛出以下异常。

2.3.4.生命周期

  1. Spring 启动,查找并加载需要被 Spring 管理的 Bean,并实例化 Bean。

  2. 利用依赖注入完成 Bean 中所有属性值的配置注入。

  3. 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。

  4. 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。

  5. 如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。

  6. 如果 Bean 实现了 [BeanPostProcessor] 接口,则 Spring 调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。

  7. 如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。

  8. 如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。

  9. 如果 [BeanPostProcessor ]和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。

  10. 如果在 中指定了该 Bean 的作用域为 singleton,则将该 Bean 放入 Spring IoC 的缓存池中,触发 Spring 对该 Bean 的生命周期管理; 如果在 中指定了该 Bean 的作用域为 prototype,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。

  11. 如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法销毁 Bean;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

2.3.4.1.单例

public class UserBean 
	private String name;  

    public UserBean()  
        System.out.println("UserBean()构造函数");  
      
    public String getName()   
        return name;  
      
    public void setName(String name)   
        System.out.println("setName()");  
        this.name = name;  
      
    public void init()  
        System.out.println("this is init of UserBean");  
      

    public void destory()  
        System.out.println("this is destory of UserBean " + this);  
      


<bean id="user_singleton" class="com.wyl.userBean" scope="singleton" 
			init-method="init" destroy-method="destory" lazy-init="true"/>

当scope=“singleton”,即默认情况下,会在启动容器时(即实例化容器时)时实例化。但我们可以指定Bean节点的lazy-init="true"来延迟初始化bean,这时候,只有在第一次获取bean时才会初始化bean,即第一次请求该bean时才初始化.

如果想对所有的默认单例bean都应用延迟初始化,可以在根节点beans设置default-lazy-init属性为true,如下所示:

<beans default-lazy-init="true">

public class LifeTest 
	@Test 
	public void test() 
		AbstractApplicationContext container = 
		new ClassPathXmlApplicationContext("user.xml");
		UserBean user = (UserBean)container.getBean("user_singleton");
		System.out.println(user);
		container.close();
	


UserBean()构造函数
this is init of UserBean
com.wyl.UserBean@573f2bb1
……
this is destory of UserBeancom.wyl.UserBean@573f2bb1

默认情况下,Spring在读取xml文件的时候,就会创建对象。在创建对象的时候先调用构造器[UserBean(),然后调用init-method属性值中所指定的方法。对象在被销毁的时候,会调用destroy-method属性值中所指定的方法.

2.3.4.2.非单例管理的对象

当scope="prototype"时,容器也会延迟初始化bean,Spring读取xml文件的时候,并不会立刻创建对象,而是在第一次请求该bean时才初始化(如调用getBean方法时)。

在第一次请求每一个prototype的bean时,Spring容器都会调用其构造器创建这个对象,然后调用init-method属性值中所指定的方法。对象销毁的时候,Spring容器不会帮我们调用任何方法,因为是非单例,这个类型的对象有很多个,Spring容器一旦把这个对象交给你之后,就不再管理这个对象了。

<bean id="user_prototype" class="com.bean.UserBean" scope="prototype" init-method="init" destroy-method="destroy"/>

public class UserTest 
	@Test 
	public void test() 
		AbstractApplicationContext container = new ClassPathXmlApplicationContext("User.xml");
		UserBean User1 = (UserBean)container.getBean("User_singleton");
		System.out.println(User1);

		UserBean User2 = (UserBean)container.getBean("User_prototype");
		System.out.println(User2);
		container.close();
	


结果

UserBean()构造函数
this is init of UserBean
com.wyl.UserBean@573f2bb1
LifeBean()构造函数
this is init of UserBean
com.wyl.UserBean@5ae9a829
……
this is destory of lifeBean com.wyl.UserBean@573f2bb1

2.4.DI(依赖注入)

依赖注入Dependency Injection,在解耦的过程中,我们将对象的创建交给Spring容器管理,当我们需要用其他类的对象,由Spring提供,我们只需在配置文件里声明即可。A类使用B类,就产生依赖关系,Spring给我们解决依赖关系就是依赖注入(DI)

2.4.1.构造器注入

private String name;
private Integer age;
private Date birthday;
// 构造函数
public UserServiceImpl(String name, Integer age, Date birthday) 
this.name = name;
this.age = age;
this.birthday = birthday;


<!-- name:按字段名称辅助;index:字段索引,给第几个字段赋值;type:指定注入值的类型,该类型也是构造函数中某个或某些字段的类型; -->
<!-- value:要注入的值,基本类型和String;ref:注入其他类型数据,指向外部bean对象;这个外部bean需要存在于Spring容器 -->
<bean id="userService" class="org.service.impl.UserServiceImpl">
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="age" value="12"/>
    <constructor-arg name="birthday" ref="date"/>
</bean>
<!-- 创建日期对象 -->
<bean id="date" class="java.util.Date"/>

2.4.2.Set方式注入

private String name;
private Integer age;
private Date birthday;
public void setName(String name) 
    this.name = name;


public void setAge(Integer age) 
    this.age = age;


public void setBirthday(Date birthday) 
    this.birthday = birthday;


<bean id="userService2" class="org.service.impl.UserServiceImpl2">
    <property name="name" value="李四"/>
    <property name="age" value="12"/>
    <property name="birthday" ref="date"/>
</bean>
<!-- 创建日期对象 -->
<bean id="date" class="java.util.Date"/>

2.4.3.对象类型注入

<!-- 注入对象类型属性 -->
<!-- 1 配置service和dao对象 -->
<bean id="userDao" class="cn.ioc.UserDao"></bean>
<bean id="userService" class="cn.ioc.UserService">
    <!-- 注入dao对象-->
    <property name="userDao" refNacos与Spring快速入门

c++基础篇——类与对象入门(下)

小白都能看懂的 Spring Boot 入门指南!

c++基础篇——类与对象入门(下)

SpringBoot快速入门

springboot:快速入门