当前位置:   article > 正文

spring6(概念;ioc详解,各种数据的注入方式)

spring6

第一章 启示录

一个普通的三层架构,不借助spring的情况下。需要程序员自己去new对象。

如果使用这种方式,那么代码上就把功能写死了,这时候需要更改一个数据库连接。这是时候数据交互层的代码就需要修改。这违背了OCP开闭原则。

 1.1 OCP开闭原则

概念: 对扩展开放,对修改关闭。也就是说在开发的过程中可以对功能扩展,添加额外的类时没有为题的,但是为了扩展功能去修改之前运行成功的代码,这是不被容许的因为一旦修改了之前运行正常的程序,就导致整体项目都要全方位的测试。

程序员自己new对象的三层架构,这里出现的问题是代码和代码之间的耦合度太大

 可以很明显的看出,上层是依赖下层的。UserController依赖UserServiceImpl,而UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致下面只要改动上面必然会受牵连(跟着也会改),所谓牵一发而动全身。这样也就同时违背了另一个开发原则:依赖倒置原则。

1.2 依赖倒置原则DIP

概念 :提倡面向抽象编程,面向接口编程,不要面向具体编程。让上层不在依赖下层。下面改动了,上面的代码也不需要修改。这样可以大大降低程序的耦合度,耦合度低了,扩展力就强了,同时代码复用性也会增强。(软件七大开发原则都是在为解耦合服务

这种方式是具体的实现类的形式 。并不算完全的面向接口编程,如果这个时候需要使用其他的实现类,这时候就需要修改具体的实现类,这样就违背了OCP原则。同时这个时候也对下层的依赖很高,依赖具体的实现类,所有也违背了DIP原则。解决方式:

 这样创建出来的是接口对象,可以使用这个接口的所有实现类,大大降低了耦合度。但是在这里定义之后不new,这个对象的值就是null,容易出现空指针异常,所以就需要使用spring中的控制反转(IOC)。

控制反转做到了两件事:

  • 负责对象的创建:也就是谁来创建这个具体的实现类对象。
  • 负责把创建的对象赋值到这里

控制反转的出现解决了这个问题,符合了OCP和DIP两个原则。

到了这个时候,程序员就不必关系具体创建哪个实现类来完成想要的功能了,只需要定义一个接口,由spring去帮你创建这个具体的实现类对象 。而这个对象是面向mysql还是oracle和上层没有关系。

1.3 控制反转IoC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计思想,可以用来降低代码之间的耦合度,符合依赖倒置原则。

控制反转的核心是:将对象的创建权交出去,将对象和对象之间关系的管理权交出去,由第三方容器来负责创建与维护

控制反转常见的实现方式:依赖注入(Dependency Injection,简称DI)

通常,依赖注入的实现由包括两种方式:

  • set方法注入
  • 构造方法注入

而Spring框架就是一个实现了IoC思想的框架。

IoC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中。(GoF指的是23种设计模式)

 第二章、Spring

2.1 Spring简介

Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。

从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

Spring最初的出现是为了解决EJB臃肿的设计,以及难以测试等问题。

Spring为简化开发而生,让程序员只需关注核心业务的实现,尽可能的不再关注非业务逻辑代码(事务控制,安全日志等)。

2.2 Spring8大模块

注意:Spring5版本之后是8个模块。在Spring5中新增了WebFlux模块。

Spring Core模块

这是Spring框架最基础的部分,它提供了依赖注入(DependencyInjection)特征来实现容器对Bean的管理。核心容器的主要组件是 BeanFactory,BeanFactory是工厂模式的一个实现,是任何Spring应用的核心。它使用IoC将应用配置和依赖从实际的应用代码中分离出来。

Spring Context模块

如果说核心模块中的BeanFactory使Spring成为容器的话,那么上下文模块就是Spring成为框架的原因。

这个模块扩展了BeanFactory,增加了对国际化(I18N)消息、事件传播、验证的支持。另外提供了许多企业服务,例如电子邮件、JNDI访问、EJB集成、远程以及时序调度(scheduling)服务。也包括了对模版框架例如Velocity和FreeMarker集成的支持

Spring AOP模块

Spring在它的AOP模块中提供了对面向切面编程的丰富支持,Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中,可以自定义拦截器、切点、日志等操作。

Spring DAO模块

提供了一个JDBC的抽象层和异常层次结构,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析,用于简化JDBC。

Spring ORM模块

Spring提供了ORM模块。Spring并不试图实现它自己的ORM解决方案,而是为几种流行的ORM框架提供了集成方案,包括Hibernate、JDO和iBATIS SQL映射,这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

Spring Web MVC模块

Spring为构建Web应用提供了一个功能全面的MVC框架。虽然Spring可以很容易地与其它MVC框架集成,例如Struts,但Spring的MVC框架使用IoC对控制逻辑和业务对象提供了完全的分离。

Spring WebFlux模块

Spring Framework 中包含的原始 Web 框架 Spring Web MVC 是专门为 Servlet API 和 Servlet 容器构建的。反应式堆栈 Web 框架 Spring WebFlux 是在 5.0 版的后期添加的。它是完全非阻塞的,支持反应式流(Reactive Stream)背压,并在Netty,Undertow和Servlet 3.1+容器等服务器上运行。

Spring Web模块

Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文,提供了Spring和其它Web框架的集成,比如Struts、WebWork。还提供了一些面向服务支持,例如:实现文件上传的multipart请求。

 2.3 Spring特点

 1.轻量

从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。

Spring是非侵入式的:Spring应用中的对象不依赖于Spring的特定类。

非侵入式:spring中的东西不依赖于外部的东西,比如不依赖tomcat服务器中的数据等。

2.控制反转

Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

 3.面向切面

Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

4.容器

Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。

5.框架

Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。

所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。

第三章、spring入门程序

 spring的jar文件

JAR文件

spring-aop-5.3.9.jar

spring-aspects-5.3.9.jar

spring-beans-5.3.9.jar

spring-context-5.3.9.jar

spring-context-indexer-5.3.9.jar

spring-context-support-5.3.9.jar

spring-core-5.3.9.jar

spring-expression-5.3.9.jar

spring-instrument-5.3.9.jar

spring-jcl-5.3.9.jar

spring-jdbc-5.3.9.jar

spring-jms-5.3.9.jar

spring-messaging-5.3.9.jar

spring-orm-5.3.9.jar

spring-oxm-5.3.9.jar

spring-r2dbc-5.3.9.jar

spring-test-5.3.9.jar

spring-tx-5.3.9.jar

spring-web-5.3.9.jar

spring-webflux-5.3.9.jar

spring-webmvc-5.3.9.jar

spring-websocket-5.3.9.jar

如果你只是想用Spring的IoC功能,仅需要引入:spring-context即可。将这个jar包添加到classpath当中。或者使用maven直接引入

 第一个spring6程序:

想要使用spring的6版本,首先得引入他的远程仓库

第一步引入依赖: 

  1. <repositories>
  2. <repository>
  3. <id>repository.spring.milestone</id>
  4. <name>Spring Milestone Repository</name>
  5. <url>https://repo.spring.io/milestone</url>
  6. </repository>
  7. </repositories>
  8. <dependencies>
  9. <!--spring context依赖-->
  10. <dependency>
  11. <groupId>org.springframework</groupId>
  12. <artifactId>spring-context</artifactId>
  13. <version>6.0.0-M2</version>
  14. </dependency>
  15. </dependencies>

第二步:定义 bean:User

  1. package com.powernode.spring6.bean;
  2. public class User {
  3. }

 第三步:编写配置文件

  1. <?xml version="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="userBean" class="com.powernode.spring6.bean.User"/>
  6. </beans>

bean的id和class属性:

  • id属性:代表对象的唯一标识。可以看做一个人的身份证号。
  • class属性:用来指定要创建的java对象的类名,这个类名必须是全限定类名(带包名)

这个时候就 可以通过spring来获取到创建的bean对象了

  1. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
  2. // 根据id获取bean对象
  3. Object userBean = applicationContext.getBean("userBean");
  4. System.out.println(userBean);

 入门程序的详细剖析

1.bean标签的id属性可以重复吗?

  1. <?xml version="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="userBean" class="com.powernode.spring6.bean.User"/>
  6. <bean id="userBean" class="com.powernode.spring6.bean.Vip"/>
  7. </beans>

 执行的时候报错;通过测试得出:在spring的配置文件中id是不能重名。

2.底层是怎么创建对象的,是通过反射机制调用无参数构造方法吗?

 在类里面添加上无惨构造方法:

  1. public class User {
  2. public User() {
  3. System.out.println("User的无参数构造方法执行");
  4. }
  5. }

通过测试得知:创建对象时确实调用了无参数构造方法。

值得注意的是:spring在使用无参构造方法创建对象的时候,会调用无参数构造方法,你如果这个时候创建了一个有参数的构造方法但是不创建无参数的,会直接报错。

如果你什么都不创建,spring会默认创建。 

Spring是如何创建对象的呢?原理是什么?

  1. // dom4j解析beans.xml文件,从中获取class的全限定类名
  2. // 通过反射机制调用无参数构造方法创建对象
  3. Class clazz = Class.forName("com.powernode.spring6.bean.User");
  4. Object obj = clazz.newInstance();

3.getBean()方法返回的类型是Object,如果访问子类的特有属性和方法时,还需要向下转型,有其它办法可以解决这个问题吗?

User user = applicationContext.getBean("userBean", User.class);

spring6兼容Log4j2日志框架

第一步:引入Log4j2的依赖 

  1. <!--log4j2的依赖-->
  2. <dependency>
  3. <groupId>org.apache.logging.log4j</groupId>
  4. <artifactId>log4j-core</artifactId>
  5. <version>2.19.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.logging.log4j</groupId>
  9. <artifactId>log4j-slf4j2-impl</artifactId>
  10. <version>2.19.0</version>
  11. </dependency>

第二步:在类的根路径下提供log4j2.xml配置文件(文件名固定为:log4j2.xml,文件必须放到类根路径下。)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <loggers>
  4. <!--
  5. level指定日志级别,从低到高的优先级:
  6. ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
  7. -->
  8. <root level="DEBUG">
  9. <appender-ref ref="spring6log"/>
  10. </root>
  11. </loggers>
  12. <appenders>
  13. <!--输出日志信息到控制台-->
  14. <console name="spring6log" target="SYSTEM_OUT">
  15. <!--控制日志输出的格式-->
  16. <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
  17. </console>
  18. </appenders>
  19. </configuration>

第三步:使用日志框架

  1. Logger logger = LoggerFactory.getLogger(FirstSpringTest.class);
  2. logger.info("我是一条日志消息");

第四章、spring对IOC的实现

4.1 IoC 控制反转

  • 控制反转是一种思想。
  • 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。
  • 控制反转,反转的是什么?
    • 将对象的创建权利交出去,交给第三方容器负责。
    • 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
  • 控制反转这种思想如何实现呢?
    • DI(Dependency Injection):依赖注入

4.2 依赖注入

依赖注入实现了控制反转的思想。

Spring通过依赖注入的方式来完成Bean管理的。

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

依赖注入:

  • 依赖指的是对象和对象之间的关联关系。
  • 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。

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

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

 

4.2.1 set注入

set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种方式要求属性必须对外提供set方法。

  1. public class UserService {
  2. private UserDao userDao;
  3. // 使用set方式注入,必须提供set方法。
  4. // 反射机制要调用这个方法给属性赋值的。
  5. public void setUserDao(UserDao userDao) {
  6. this.userDao = userDao;
  7. }
  8. public void save(){
  9. userDao.insert();
  10. }
  11. }
  1. <?xml version="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="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
  6. <bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
  7. <property name="userDao" ref="userDaoBean"/>
  8. </bean>
  9. </beans>

实现原理:

通过property标签获取到属性名:userDao

通过属性名推断出set方法名:setUserDao

通过反射机制调用setUserDao()方法给属性赋值

property标签的name是属性名。

property标签的ref是要注入的bean对象的id。(通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。装配指的是:创建系统组件之间关联的动作)

4.2.2 构造注入

核心原理:通过调用构造方法来给属性赋值。

构造注入的赋值方式有很多,可以参数下标,可以属性名,也可以都不指定

  1. public class OrderService {
  2. private OrderDao orderDao;
  3. // 通过反射机制调用构造方法给属性赋值
  4. public OrderService(OrderDao orderDao) {
  5. this.orderDao = orderDao;
  6. }
  7. public void delete(){
  8. orderDao.deleteById();
  9. }
  10. }
  1. <bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>
  2. <bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService">
  3. <!--index="0"表示构造方法的第一个参数,将orderDaoBean对象传递给构造方法的第一个参数。-->
  4. <constructor-arg index="0" ref="orderDaoBean"/>
  5. </bean>

通过测试得知,通过构造方法注入的时候:

  • 可以通过下标
  • 可以通过参数名
  • 也可以不指定下标和参数名,可以类型自动推断。

Spring在装配方面做的还是比较健壮的。

4.3 set注入专题

4.3.1 注入外部Bean

  1. <?xml version="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="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
  6. <bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
  7. <property name="userDao" ref="userDaoBean"/>
  8. </bean>
  9. </beans>

外部Bean的特点:bean定义到外面,在property标签中使用ref属性进行注入。通常这种方式是常用。

4.3.2 注入内部Bean

内部Bean的方式:在bean标签中嵌套bean标签。

  1. <?xml version="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="userServiceBean" class="com.powernode.spring6.service.UserService">
  6. <property name="userDao">
  7. <bean class="com.powernode.spring6.dao.UserDao"/>
  8. </property>
  9. </bean>
  10. </beans>

4.3.3 注入简单类型

  1. <?xml version="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="userBean" class="com.powernode.spring6.beans.User">
  6. <!--如果像这种int类型的属性,我们称为简单类型,这种简单类型在注入的时候要使用value属性,不能使用ref-->
  7. <!--<property name="age" value="20"/>-->
  8. <property name="age">
  9. <value>20</value>
  10. </property>
  11. </bean>
  12. </beans>

需要特别注意:如果给简单类型赋值,使用value属性或value标签。而不是ref。

通过spring源码来分析一下简单类型包括哪些: BeanUtils类

  1. public class BeanUtils{
  2. //.......
  3. /**
  4. * Check if the given type represents a "simple" property: a simple value
  5. * type or an array of simple value types.
  6. * <p>See {@link #isSimpleValueType(Class)} for the definition of <em>simple
  7. * value type</em>.
  8. * <p>Used to determine properties to check for a "simple" dependency-check.
  9. * @param type the type to check
  10. * @return whether the given type represents a "simple" property
  11. * @see org.springframework.beans.factory.support.RootBeanDefinition#DEPENDENCY_CHECK_SIMPLE
  12. * @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#checkDependencies
  13. * @see #isSimpleValueType(Class)
  14. */
  15. public static boolean isSimpleProperty(Class<?> type) {
  16. Assert.notNull(type, "'type' must not be null");
  17. return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
  18. }
  19. /**
  20. * Check if the given type represents a "simple" value type: a primitive or
  21. * primitive wrapper, an enum, a String or other CharSequence, a Number, a
  22. * Date, a Temporal, a URI, a URL, a Locale, or a Class.
  23. * <p>{@code Void} and {@code void} are not considered simple value types.
  24. * @param type the type to check
  25. * @return whether the given type represents a "simple" value type
  26. * @see #isSimpleProperty(Class)
  27. */
  28. public static boolean isSimpleValueType(Class<?> type) {
  29. return (Void.class != type && void.class != type &&
  30. (ClassUtils.isPrimitiveOrWrapper(type) ||
  31. Enum.class.isAssignableFrom(type) ||
  32. CharSequence.class.isAssignableFrom(type) ||
  33. Number.class.isAssignableFrom(type) ||
  34. Date.class.isAssignableFrom(type) ||
  35. Temporal.class.isAssignableFrom(type) ||
  36. URI.class == type ||
  37. URL.class == type ||
  38. Locale.class == type ||
  39. Class.class == type));
  40. }
  41. //........
  42. }

通过源码分析得知,简单类型包括:

  • 基本数据类型
  • 基本数据类型对应的包装类
  • String或其他的CharSequence子类
  • Number子类
  • Date子类
  • Enum子类
  • URI
  • URL
  • Temporal子类
  • Locale
  • Class
  • 另外还包括以上简单值类型对应的数组类型。

 案例:给数据源的属性注入值,首先一个数据源需要实现javax.sql.DataSource接口

  1. public class MyDataSource implements DataSource {
  2. private String driver;
  3. private String url;
  4. private String username;
  5. private String password;
  6. @Override
  7. public Connection getConnection() throws SQLException {
  8. return null;
  9. }
  10. @Override
  11. public Connection getConnection(String username, String password) throws SQLException {
  12. return null;
  13. }
  14. @Override
  15. public PrintWriter getLogWriter() throws SQLException {
  16. return null;
  17. }
  18. @Override
  19. public void setLogWriter(PrintWriter out) throws SQLException {
  20. }
  21. @Override
  22. public void setLoginTimeout(int seconds) throws SQLException {
  23. }
  24. @Override
  25. public int getLoginTimeout() throws SQLException {
  26. return 0;
  27. }
  28. @Override
  29. public Logger getParentLogger() throws SQLFeatureNotSupportedException {
  30. return null;
  31. }
  32. @Override
  33. public <T> T unwrap(Class<T> iface) throws SQLException {
  34. return null;
  35. }
  36. @Override
  37. public boolean isWrapperFor(Class<?> iface) throws SQLException {
  38. return false;
  39. }
  40. }
  1. <?xml version="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="dataSource" class="com.powernode.spring6.beans.MyDataSource">
  6. <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
  7. <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
  8. <property name="username" value="root"/>
  9. <property name="password" value="123456"/>
  10. </bean>
  11. </beans>

各种简单类型的注入方式:

 

  1. <bean id="a" class="com.powernode.spring6.beans.A">
  2. <property name="b" value="1"/>
  3. <property name="s" value="1"/>
  4. <property name="i" value="1"/>
  5. <property name="l" value="1"/>
  6. <property name="f" value="1"/>
  7. <property name="d" value="1"/>
  8. <property name="flag" value="false"/>
  9. 八种简单类型和八种包装类型
  10. <property name="c" value="a"/>
  11. <property name="b1" value="2"/>
  12. <property name="s1" value="2"/>
  13. <property name="i1" value="2"/>
  14. <property name="l1" value="2"/>
  15. <property name="f1" value="2"/>
  16. <property name="d1" value="2"/>
  17. <property name="flag1" value="true"/>
  18. <property name="c1" value="a"/>
  19. <property name="str" value="zhangsan"/>
  20. <!--注意:value后面的日期字符串格式不能随便写,必须是Date对象toString()方法执行的结果。-->
  21. <!--如果想使用其他格式的日期字符串,就需要进行特殊处理了。具体怎么处理,可以看后面的课程!!!!-->
  22. <property name="date" value="Fri Sep 30 15:26:38 CST 2022"/>
  23. <property name="season" value="WINTER"/>
  24. <property name="uri" value="/save.do"/>
  25. <!--spring6之后,会自动检查url是否有效,如果无效会报错。-->
  26. <property name="url" value="http://www.baidu.com"/>
  27. <property name="localDate" value="EPOCH"/>
  28. <!--java.util.Locale 主要在软件的本地化时使用。它本身没有什么功能,更多的是作为一个参数辅助其他方法完成输出的本地化。-->
  29. <property name="locale" value="CHINESE"/>
  30. <property name="clazz" value="java.lang.String"/>
  31. </bean>

需要注意的是:

  • 如果把Date当做简单类型的话,日期字符串格式不能随便写。格式必须符合Date的toString()方法格式。显然这就比较鸡肋了。如果我们提供一个这样的日期字符串:2010-10-11,在这里是无法赋值给Date类型的属性的。
  • spring6之后,当注入的是URL,那么这个url字符串是会进行有效性检测的。如果是一个存在的url,那就没问题。如果不存在则报错。

4.3.4 级联属性赋值(了解)

给对象中的对象的属性赋值

  1. <bean id="clazzBean" class="com.powernode.spring6.beans.Clazz"/>
  2. <bean id="student" class="com.powernode.spring6.beans.Student">
  3. <property name="name" value="张三"/>
  4. <!--要点1:以下两行配置的顺序不能颠倒-->
  5. <property name="clazz" ref="clazzBean"/>
  6. <!--要点2:clazz属性必须有getter方法-->
  7. <property name="clazz.name" value="高三一班"/>
  8. </bean>

要点:

  • 在spring配置文件中,如上,注意顺序。
  • 在spring配置文件中,clazz属性必须提供getter方法。

 

4.3.5 注入数组

当数组中的元素是简单类型

  1. <bean id="person" class="com.powernode.spring6.beans.Person">
  2. <property name="favariteFoods">
  3. <array>
  4. <value>鸡排</value>
  5. <value>汉堡</value>
  6. <value>鹅肝</value>
  7. </array>
  8. </property>
  9. </bean>

 当数组中的元素是非简单类型:一个订单中包含多个商品。

  1. <bean id="goods1" class="com.powernode.spring6.beans.Goods">
  2. <property name="name" value="西瓜"/>
  3. </bean>
  4. <bean id="goods2" class="com.powernode.spring6.beans.Goods">
  5. <property name="name" value="苹果"/>
  6. </bean>
  7. <bean id="order" class="com.powernode.spring6.beans.Order">
  8. <property name="goods">
  9. <array>
  10. <!--这里使用ref标签即可-->
  11. <ref bean="goods1"/>
  12. <ref bean="goods2"/>
  13. </array>
  14. </property>
  15. </bean>

4.3.6 注入List集合

List集合:有序可重复

  1. <bean id="peopleBean" class="com.powernode.spring6.beans.People">
  2. <property name="names">
  3. <list>
  4. <value>铁锤</value>
  5. <value>张三</value>
  6. <value>张三</value>
  7. <value>张三</value>
  8. <value></value>
  9. </list>
  10. </property>
  11. </bean>

4.3.7 注入Set集合

Set集合:无序不可重复

  1. <bean id="peopleBean" class="com.powernode.spring6.beans.People">
  2. <property name="phones">
  3. <set>
  4. <!--非简单类型可以使用ref,简单类型使用value-->
  5. <value>110</value>
  6. <value>110</value>
  7. <value>120</value>
  8. <value>120</value>
  9. <value>119</value>
  10. <value>119</value>
  11. </set>
  12. </property>
  13. </bean>

 4.3.8 注入Map集合

  1. <bean id="peopleBean" class="com.powernode.spring6.beans.People">
  2. <property name="addrs">
  3. <map>
  4. <!--如果key不是简单类型,使用 key-ref 属性-->
  5. <!--如果value不是简单类型,使用 value-ref 属性-->
  6. <entry key="1" value="北京大兴区"/>
  7. <entry key="2" value="上海浦东区"/>
  8. <entry key="3" value="深圳宝安区"/>
  9. </map>
  10. </property>

 

4.3.9 注入Properties

java.util.Properties继承java.util.Hashtable,所以Properties也是一个Map集合。

  1. <bean id="peopleBean" class="com.powernode.spring6.beans.People">
  2. <property name="properties">
  3. <props>
  4. <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
  5. <prop key="url">jdbc:mysql://localhost:3306/spring</prop>
  6. <prop key="username">root</prop>
  7. <prop key="password">123456</prop>
  8. </props>
  9. </property>
  10. </bean>

 4.3.10 注入null和空字符串

注入空字符串使用:<value/> 或者 value=""

这种方式的属性值有值,但是一个空字符串,不是null

注入null使用:<null/> 或者 不为该属性赋值

这种该方式是一个null,不可使用

  1. <?xml version="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="vipBean" class="com.powernode.spring6.beans.Vip">
  6. <property name="email">
  7. <null/>
  8. </property>
  9. </bean>
  10. </beans>

 4.3.11 注入的值中含有特殊符号

XML中有5个特殊字符,分别是:<、>、'、"、&

以上5个特殊符号在XML中会被特殊对待,会被当做XML语法的一部分进行解析,如果这些特殊符号直接出现在注入的字符串当中,会报错。

解决方案包括两种:

  • 第一种:特殊符号使用转义字符代替。
  • 第二种:将含有特殊符号的字符串放到:<![CDATA[]]> 当中。因为放在CDATA区中的数据不会被XML文件解析器解析。

5个特殊字符对应的转义字符分别是:

特殊字符

转义字符

>

>

<

<

'

'

"

"

&

&

 

  1. <?xml version="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="mathBean" class="com.powernode.spring6.beans.Math">
  6. <property name="result" value="2 &lt; 3"/>
  7. </bean>
  8. </beans>
  1. <?xml version="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="mathBean" class="com.powernode.spring6.beans.Math">
  6. <property name="result">
  7. <!--只能使用value标签-->
  8. <value><![CDATA[2 < 3]]></value>
  9. </property>
  10. </bean>
  11. </beans>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/327872
推荐阅读
相关标签
  

闽ICP备14008679号