本篇会给咱们举出各种Spring特点依靠注入的例子,便利咱们了解。

1. setter特点注入

1.1 运用XML进行setter办法注入

咱们在前面的文章中现已运用过XML进行setter办法的特点注入了,下面让咱们再来回忆一下:

<bean id="userSetter" class="com.example.demo.bean.User">
    <property name="username" value="example-username-setter"/>
    <property name="age" value="25"/>
</bean>

1.2 运用@Bean注解进行setter办法注入

咱们在前面的文章中也学习过如安在bean创立时经过编程办法设置特点:

@Bean
public User user() {
    User user = new User();
    user.setUsername("example-username-anno-setter");
    user.setAge(25);
    return user;
}

1.3 setter办法注入完好代码示例

  • 运用XML进行setter办法注入

首要,咱们需求创立一个User类,并在其中包含usernameage两个特点,以及相应的gettersetter办法和结构器。

public class User {
    private String username;
    private Integer age;
    public User() {}
	// 为了节约篇幅,getter和setter办法省掉......
    @Override
    public String toString() {
        return "User{username='" + username + "', age=" + age + "}";
    }
}

关于XML办法的setter注入和结构器注入,咱们需求创立一个装备文件,比如叫applicationContext.xml

<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">
    <!-- setter办法注入 -->
    <bean id="userSetter" class="com.example.demo.bean.User">
        <property name="username" value="example-username-setter"/>
        <property name="age" value="25"/>
    </bean>
</beans>

然后,咱们需求创立一个DemoApplication类,运用ApplicationContext来加载装备文件并获取Bean

import com.example.demo.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User userSetter = (User) context.getBean("userSetter");
        System.out.println(userSetter);
    }
}

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  • 运用@Bean注解进行setter办法注入

咱们需求创立一个装备类,例如叫AppConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
    @Bean
    public User userSetter() {
        User user = new User();
        user.setUsername("example-username-anno-setter");
        user.setAge(25);
        return user;
    }
}

运用@Bean注解来界说Bean。每个@Bean办法对应于XML装备中的一个<bean>元素。这个办法的称号便是Beanid,办法的回来值便是Bean的类型

然后修正主程序,这儿运用AnnotationConfigApplicationContext来创立Spring的运用上下文,并加载装备类。Spring会主动从装备类中获取一切的Bean界说,并创立相应的Bean实例。

package com.example.demo;
import com.example.demo.bean.User;
import com.example.demo.configuration.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        User userSetter = (User) context.getBean("userSetter");
        System.out.println(userSetter);
    }
}

运转成果如下

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  留意:XML装备办法现已相对陈旧,而且在Spring Boot项目中,主流的做法是运用注解和Java装备办法。关于setter注入,有时会引发循环依靠的问题。在Spring中,能够运用结构器注入来避免这种情况,这儿了解即可。


2. 结构器注入

  setter注入是一种在目标被实例化之后(经过调用无参结构器创立实例)再经过setter办法注入依靠的办法。结构器注入则是在创立目标实例的时候就经过结构器参数来注入依靠。

为了演示结构器注入,咱们需求给User添加一个全参数结构器:

public User(String username, Integer age) {
    this.username = username;
    this.age = age;
}

添加这个结构器后,Java不再供给默许的无参结构器,这会导致咱们之前的<bean>标签创立时失败,由于它找不到默许的结构器。

2.1 运用XML进行结构器注入

咱们能够在<bean>标签内部声明一个子标签:constructor-arg。它用于指定结构器的参数,来进行特点注入。constructor-arg标签的编写规矩如下:

<bean id="userConstructor" class="com.example.demo.bean.User">
    <constructor-arg index="0" value="example-username-constructor"/>
    <constructor-arg index="1" value="25"/>
</bean>

  index特点表明结构函数参数的方位,它的值是一个非负整数,其中0表明第一个参数,1表明第二个参数,以此类推。尽管value特点的值总是一个字符串,可是Spring会测验将它转换为结构函数参数所需的类型。例如结构函数的第二个参数是int类型,那么Spring会测验将字符串"25"转换为整数25

  运用index特点来指定结构函数参数的方位在大多数情况下是能够的,可是假如结构函数的参数数量或许次序发生了改变,就可能会犯错。另外一种更为可靠的办法是运用name特点来指定参数的称号,如:

<bean id="userConstructor" class="com.example.demo.bean.User">
    <constructor-arg name="username" value="example-username-constructor"/>
    <constructor-arg name="age" value="25"/>
</bean>

这样无论参数的次序如何,只需参数称号不变,就不会犯错。

2.2 运用@Bean注解进行结构器特点注入

在注解驱动的bean注册中,咱们也能够直接运用编程办法赋值:

@Bean
public User user() {
    return new User("example-username-anno-constructor", 25);
}

2.3 结构器注入的完好代码示例

  • 运用XML进行结构器注入

首要,咱们需求创立一个User类,并在其中包含usernameage两个特点,以及相应的gettersetter办法和结构器。

public class User {
    private String username;
    private Integer age;
    public User() {}
    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }
	// 为了节约篇幅,getter和setter办法省掉......
    @Override
    public String toString() {
        return "User{username='" + username + "', age=" + age + "}";
    }
}

关于XML办法的结构器注入,咱们需求创立一个装备文件,比如叫applicationContext.xml,这儿保存setter注入便利咱们比照

<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">
    <!-- setter办法注入 -->
   <!-- setter办法注入 -->
<!--    <bean id="userSetter" class="com.example.demo.bean.User">-->
<!--        <property name="username" value="example-username-setter"/>-->
<!--        <property name="age" value="25"/>-->
<!--    </bean>-->
    <!-- 结构器注入 -->
    <bean id="userConstructor" class="com.example.demo.bean.User">
	    <constructor-arg name="username" value="example-username-constructor"/>
	    <constructor-arg name="age" value="25"/>
	</bean>
</beans>

然后,咱们需求创立一个DemoApplication类,运用ApplicationContext来加载装备文件并获取Bean

package com.example.demo;
import com.example.demo.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//        User userSetter = (User) context.getBean("userSetter");
//        System.out.println(userSetter);
        User userConstructor = (User) context.getBean("userConstructor");
        System.out.println(userConstructor);
    }
}

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  • 运用@Bean注解进行结构器特点注入

咱们需求创立一个装备类,例如叫AppConfig.java

import com.example.demo.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
//    @Bean
//    public User userSetter() {
//        User user = new User();
//        user.setUsername("example-username-anno-setter");
//        user.setAge(25);
//        return user;
//    }
    @Bean
    public User userConstructor() {
        return new User("example-username-anno-constructor", 25);
    }
}

相同,咱们需求创立一个DemoApplication类,运用AnnotationConfigApplicationContext来加载装备类并获取Bean

import com.example.demo.bean.User;
import com.example.demo.configuration.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//        User userSetter = (User) context.getBean("userSetter");
//        System.out.println(userSetter);
        User userConstructor = (User) context.getBean("userConstructor");
        System.out.println(userConstructor);
    }
}

运转成果:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

留意:假如在类中一同运用结构器注入和setter注入,需求留意它们注入的次序:先进行结构器注入,然后是setter注入。


3. 注解式特点注入

  上面咱们现已说过注解式的setter和结构器注入。咱们又是如何处理那些经过@Component扫描而注册的bean的特点的呢?咱们来仔细说说这个问题,一同展现如安在xml中进行相同的操作。

3.1 @Value注解式特点注入的运用

  首要,让咱们从最简略的特点注入办法:@Value开端。创立一个新的White类,并声明一些字段,可是这次咱们不会设置setter办法:

@Component
public class White {
    @Value("white-value-annotation")
    private String title;
    @Value("1")
    private Integer rank;
    @Override
    public String toString() {
        return "White{" + "title='" + title + '\'' + ", rank=" + rank + '}';
    }
}

要完成注解式特点注入,咱们能够直接在需求注入的字段上添加@Value注解:

@Value("white-value-annotation")
private String title;
@Value("1")
private Integer rank;

要留意的是,假如运用 @Value 注解来注入一个不存在的特点,那么运用程序会在发动时抛出异常。

然后,咱们将经过组件扫描办法将这个White类扫描到IOC容器中,并将其取出并打印:

public class DemoApplication {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(White.class);
        White white = ctx.getBean(White.class);
        System.out.println("Injected value : " + white);
    }
}

运转main办法会看到White的字段现已成功注入:

Injected value : White{title='white-value-annotation', rank=1}

3.2 引进外部装备文件@PropertySource

  假如咱们需求在Spring中运用properties文件,咱们应该怎么办呢?Spring考虑到了这一点,并扩展了一个用于导入外部装备文件的注解:@PropertySource

  1. 创立Bean和装备文件

创立一个新的Blue类,其结构与White类完全相同。然后在项目的resources目录下创立一个新的blue.properties文件,用于存储Blue类的特点装备:

blue.title=blue-value-properties
blue.rank=2
  1. 引进装备文件

运用@PropertySource注解将properties文件导入到装备类:

@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:blue.properties")
public class InjectValueConfiguration {
}

  这个blue.properties文件是一个键值对的列表,Spring 将这些键值对加载到 Environment 中,咱们能够经过 @Value 注解或许 Environment 类的办法来获取这些特点值。

@Value 注解和 Environment 类都能够用于读取 Spring 上下文中的特点值。这些特点值可能来自于多个不同的源,包含但不限于:

  • Spring Boot 的默许装备文件(application.propertiesapplication.yml)。
  • 经过 @PropertySource 注解加载的特点文件。
  • 体系环境变量。
  • Java 体系特点(能够经过 -D 命令行参数设置)。

假如你想经过 @Value 注解来获取特点值,如下:

@Component
public class BlueConfig {
    @Value("${blue.title}")
    private String title;
    @Value("${blue.rank}")
    private int rank;
    // getters and setters...
}

  在 Spring 运用中运用 @PropertySource 注解来加载一个 .properties 文件时,这个文件中的一切装备项都会被读取,并存储在一个内部的 Map 结构中。这个 Map 的键是装备项的称号,值是装备项的值。Spring 中的一些内置装备项也会被添加到这个 Map 中。

  当咱们运用 ${...} 占位符语法来引证一个装备项时,Spring 会查找这个 Map,取出与占位符称号相应的装备项的值。例如有一个装备项 blue.title=blue-value-properties,咱们能够在代码中运用 ${blue.title} 占位符来引证这个装备项的值。

假如想经过 Environment 类的办法来获取特点值,能够像下面这样做:

@Component
public class SomeComponent {
    @Autowired
    private Environment env;
    public void someMethod() {
        String title = env.getProperty("blue.title");
        int rank = Integer.parseInt(env.getProperty("blue.rank"));
        // ...
    }
}

  在上述代码中,Environment 类的 getProperty 办法用于获取特点值。留意,getProperty 办法回来的是 String,所以假如特点对错字符串类型(如 int),则需求将获取的特点值转换为恰当的类型。

  留意:@PropertySource 无法加载 YAML 格局的文件,只能加载 properties 格局的文件。假如需求加载 YAML 格局的文件,而且运用的是 Spring Boot结构,那么能够运用@ConfigurationProperties@Value注解。例如以下的YAML文件:

application.yml

appTest:
  name: MyApp
  version: 1.0.0

能够运用@ConfigurationProperties来加载这些特点:

@Configuration
@ConfigurationProperties(prefix = "appTest")
public class AppConfig {
    private String name;
    private String version;
    // getters and setters...
}

  @ConfigurationProperties注解首要用于指定装备特点的前缀,@ConfigurationProperties注解自身并不直接指定装备文件的方位, 而是由Spring Boot的主动装备机制处理的。

  这样,name字段就会被主动绑定到appTest.name装备特点,version字段就会被主动绑定到appTest.version装备特点。

  默许情况下,Spring Boot会在发动时主动加载src/main/resources目录下的application.propertiesapplication.yml文件。咱们能够经过设置spring.config.namespring.config.location特点来改变默许的装备文件名或方位。

  留意:@ConfigurationProperties注解需求合作@EnableConfigurationProperties注解或@Configuration注解运用,以确保Spring能够发现并处理这些注解。

或许,你也能够运用@Value注解来加载这些特点:

@Component
public class AppConfig {
    @Value("${appTest.name}")
    private String name;
    @Value("${appTest.version}")
    private String version;
    // getters and setters...
}
  1. Blue类的特点注入

关于properties类型的特点,咱们这儿挑选@Value注解和占位符来注入特点:

@Value("${blue.title}")
private String title;
@Value("${blue.rank}")
private Integer rank;

假如你熟悉jspel表达式,会发现这和它非常类似!

  1. 测试发动类

修正发动类,将装备类引进,然后取出并打印Blue

public static void main(String[] args) throws Exception {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(InjectValueConfiguration.class);
    Blue blue = ctx.getBean(Blue.class);
    System.out.println("Properties value : " + blue);
}

运转main办法会看到控制台现已成功打印出了装备文件的特点:

Properties value : Blue{title='blue-value-properties', rank=2}

3.3 在XML中引进外部装备文件

xml中,咱们能够和@Value相同的办法运用占位符:

<?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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"
       xmlns:context="http://www.springframework.org/schema/context">
    <!-- 相当于注解中的 @PropertySource("classpath:blue.properties") -->
    <context:property-placeholder location="classpath:blue.properties"/>
    <bean class="com.example.demo.bean.Blue">
        <property name="title" value="${blue.title}"/>
        <property name="rank" value="${blue.rank}"/>
    </bean>
</beans>

3.4 注解式特点注入完好代码示例

  • @Value注解式特点注入的运用

创立White类:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class White {
    @Value("white-value-annotation")
    private String title;
    @Value("1")
    private Integer rank;
    @Override
    public String toString() {
        return "White{" + "title='" + title + '\'' + ", rank=" + rank + '}';
    }
}

创立发动类InjectValueAnnotationApplication

package com.example.demo;
import com.example.demo.bean.White;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(White.class);
        White white = ctx.getBean(White.class);
        System.out.println("Injected value : " + white);
    }
}

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  • 引进外部装备文件@PropertySource

创立Blue类和装备文件,没有settergetter办法:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Blue {
    @Value("${blue.title}")
    private String title;
    @Value("${blue.rank}")
    private Integer rank;
    @Override
    public String toString() {
        return "Blue{" + "title='" + title + '\'' + ", rank=" + rank + '}';
    }
}

resources目录下的blue.properties文件:

blue.title=blue-value-properties
blue.rank=2

创立装备类InjectValueConfiguration

package com.example.demo.configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:blue.properties")
public class InjectValueConfiguration {
}

修正发动类,引进装备类:

package com.example.demo;
import com.example.demo.bean.Blue;
import com.example.demo.configuration.InjectValueConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DemoApplication {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(InjectValueConfiguration.class);
        Blue blue = ctx.getBean(Blue.class);
        System.out.println("Properties value : " + blue);
    }
}

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  • 在xml中引进外部装备文件

  在运用XML装备的情况下,咱们需求创立一个XML文件来代替InjectValueConfiguration类,咱们能够先注释掉InjectValueConfiguration类的一切内容

下面是相应的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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"
       xmlns:context="http://www.springframework.org/schema/context">
    <!-- 相当于注解中的 @PropertySource("classpath:blue.properties") -->
    <context:property-placeholder location="classpath:blue.properties"/>
    <bean class="com.example.demo.bean.Blue">
        <property name="title" value="${blue.title}"/>
        <property name="rank" value="${blue.rank}"/>
    </bean>
</beans>

  在这儿咱们运用了context:property-placeholder标签来导入外部的properties文件,然后运用${...}占位符语法来引证装备文件中的特点值。这样无论是挑选用注解办法还是XML办法,都能够便利地在Spring中运用外部装备文件。

这儿还需求修正下Blue类,由于经过XML办法注入特点需求供给相应的setter办法,修正后的Blue类如下:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Blue {
    @Value("${blue.title}")
    private String title;
    @Value("${blue.rank}")
    private Integer rank;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Integer getRank() {
        return rank;
    }
    public void setRank(Integer rank) {
        this.rank = rank;
    }
    @Override
    public String toString() {
        return "Blue{" + "title='" + title + '\'' + ", rank=" + rank + '}';
    }
}

然后,咱们需求修正发动类,运用XmlApplicationContext代替AnnotationConfigApplicationContext

package com.example.demo;
import com.example.demo.bean.Blue;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@ComponentScan("com.example")
public class DemoApplication {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:injectValueContext.xml");
        Blue blue = ctx.getBean(Blue.class);
        System.out.println("Properties value : " + blue);
    }
}

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

4. SpEL表达式

  当咱们谈到特点注入的时候,咱们可能会遇到一些杂乱的需求,例如咱们需求引证另一个Bean的特点,或许咱们需求动态处理某个特点值。这种需求无法经过运用${}的占位符办法完成,咱们需求一个更强壮的工具:SpEL表达式。

  Spring Expression LanguageSpEL)是从Spring结构 3.0开端支撑的强壮工具。SpEL不只是Spring结构的重要组成部分,也能够独立运用。它的功用丰厚,包含调用特点值、特点参数、办法调用、数组存储以及逻辑计算等。它与开源项目OGNLObject-Graph Navigation Language)类似,但SpELSpring结构推出的,并默许内嵌在Spring结构中。

4.1 运用@Value注解和SpEL表达式完成特点注入

  SpEL的表达式用#{}表明,花括号中便是咱们要编写的表达式。

  咱们创立一个Bean,命名为Azure,相同地,咱们声明特点namepriority,并供给gettersetter办法以及toString()办法。然后咱们运用@Component注解标示它。

运用@Value合作SpEL完结特点注入,如下:

@Component
public class Azure {
    @Value("#{'spel-for-azure'}")
    private String name;
    @Value("#{10}")
    private Integer priority;
}

咱们修正发动类,从IOC容器中获取Azure并打印,能够看到特点被成功注入:

Azure{name='spel-for-azure', priority=10}

  SpEL的功用远不止这些,它还能够获取IOC容器中其他Bean的特点,让咱们来展现一下。

  咱们现已注册了Azure Bean,现在咱们再创立一个Bean,命名为Emerald。咱们依照上述办法对字段和办法进行声明,然后运用@Component注解标示。

  咱们期望name特点直接仿制Azurename特点,而priority特点则期望比Azurepriority特点大1,咱们能够这样编写:

@Component
public class Emerald {
    @Value("#{'copy of ' + azure.name}")
    private String name;
    @Value("#{azure.priority + 1}")
    private Integer priority;
}

  在SpringSpEL中能够经过bean的称号拜访到对应的bean,并经过.操作符拜访bean的特点。在这个例子中,azure便是一个bean的称号,它对应的bean便是Azure类的实例。所以,azure.name便是拜访Azure类实例的name特点。

假如你在一个不涉及Spring的环境中运用SpEL,这个特性是不会生效的。这是由于这个特性依靠于SpringIoC容器。

咱们修正发动类,测试运转,能够看到Azure的特点现已成功被仿制:

use spel bean property : Emerald{name='copy of spel-for-azure', priority=11}

  SpEL表达式不只能够引证目标的特点,还能够直接引证类的常量,以及调用目标的办法。下面咱们经过示例进行演示。

  咱们新建一个Bean,命名为Ivory。咱们依照上述办法初始化特点、toString()办法、注解。

  假设咱们有一个需求,让nameazure特点的前3个字符,priorityInteger的最大值。那么咱们能够运用SpEL这样写:

@Component
public class Ivory {
    @Value("#{azure.name.substring(0, 3)}")
    private String name;
    @Value("#{T(java.lang.Integer).MAX_VALUE}")
    private Integer priority;
}

留意,直接引证类的特点,需求在类的全限定名外面运用T()包围。

咱们修正发动类,测试运转,能够看到Ivory的特点现已是处理之后的值:

use spel methods : Ivory{name='spe', priority=2147483647}

4.2 在XML中运用SpEL表达式完成特点注入:

<bean id="ivory" class="com.example.demo.bean.Ivory">
    <property name="name" value="#{azure.name.substring(0, 3)}" />
    <property name="priority" value="#{T(java.lang.Integer).MAX_VALUE}" />
</bean>

学习SpEL表达式不需求花费很多的精力,掌握基础的运用办法即可。

4.3 SpEL表达式特点注入完好代码示例

  • 运用@Value注解和SpEL表达式完成特点注入

创立三个SpEL表达式特点注入的BeanAzure.javaEmerald.javaIvory.java

Azure.java:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Azure {
    @Value("#{'spel-for-azure'}")
    private String name;
    @Value("#{10}")
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Azure{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

Emerald.java:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Emerald {
    @Value("#{'copy of ' + azure.name}")
    private String name;
    @Value("#{azure.priority + 1}")
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Emerald{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

Ivory.java:

package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Ivory {
    @Value("#{azure.name.substring(0, 3)}")
    private String name;
    @Value("#{T(java.lang.Integer).MAX_VALUE}")
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Ivory{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

MyBean.java

@Component
public class MyBean {
    @Autowired
    private Azure azure;
    @Autowired
    private Emerald emerald;
    @Autowired
    private Ivory ivory;
    public void init() {
        System.out.println(azure);
        System.out.println(emerald);
        System.out.println(ivory);
    }
}

  MyBean是一个用于展现如安在Spring中经过SpEL表达式来注入特点的类,它聚合了三个目标Azure, EmeraldIvory,并经过Spring的依靠注入机制将这三个目标注入到了MyBean类的实例中

主程序DemoApplication

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        MyBean myBean = applicationContext.getBean(MyBean.class);
        myBean.init();
    }
}

运转成果:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

  • 在XML中运用SpEL表达式完成特点注入

  关于XML装备,Spring还支撑在bean界说中运用SpEL

首要,需求创立一个Spring XML装备文件,咱们将其命名为app-config.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"
       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.example" />
    <bean id="azure" class="com.example.demo.bean.Azure">
        <property name="name" value="#{'spel-for-azure'}" />
        <property name="priority" value="#{10}" />
    </bean>
    <bean id="emerald" class="com.example.demo.bean.Emerald">
        <property name="name" value="#{'copy of ' + azure.name}" />
        <property name="priority" value="#{azure.priority + 1}" />
    </bean>
    <bean id="ivory" class="com.example.demo.bean.Ivory">
        <property name="name" value="#{azure.name.substring(0, 3)}" />
        <property name="priority" value="#{T(java.lang.Integer).MAX_VALUE}" />
    </bean>
</beans>

留意:在XML中运用SpEL需求运用#{},而不是${}

  然后修正这3Bean,假如是运用XML来装备SpringBean的话,那么在Java类中就不需求运用@Component注解了。由于XML装备文件现已明确地告诉Spring这些类是Spring Bean

  相同的,假如在XML文件中界说了Bean的特点值,那么在Java类中就不需求运用@Value注解来注入这些值了。由于XML装备文件现已明确地为这些特点赋了值。

Azure.java

package com.example.demo.bean;
public class Azure {
    private String name;
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Azure{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

Emerald.java

package com.example.demo.bean;
public class Emerald {
    private String name;
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Emerald{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

Ivory.java

package com.example.demo.bean;
public class Ivory {
    private String name;
    private Integer priority;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPriority() {
        return priority;
    }
    public void setPriority(Integer priority) {
        this.priority = priority;
    }
    @Override
    public String toString() {
        return "Ivory{" +
                "name='" + name + '\'' +
                ", priority=" + priority +
                '}';
    }
}

然后需求在主程序中导入这个XML装备文件,这能够经过在主程序中添加@ImportResource注解完成:

package com.example.demo;
import com.example.demo.bean.MyBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("classpath:app-config.xml")
public class DemoApplication {
    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        MyBean myBean = applicationContext.getBean(MyBean.class);
        myBean.init();
    }
}

这样就能够在SpringXML装备文件中运用SpEL了。

运转成果如下:

Spring高手之路3——揭秘Spring依赖注入和SpEL表达式



欢迎一键三连~

有问题请留言,咱们一同讨论学习

———————-Talk is cheap, show me the code———————–