本篇会给咱们举出各种
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
类,并在其中包含username
和age
两个特点,以及相应的getter
、setter
办法和结构器。
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);
}
}
运转成果如下:
- 运用@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>
元素。这个办法的称号便是Bean
的id
,办法的回来值便是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);
}
}
运转成果如下
留意: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
类,并在其中包含username
和age
两个特点,以及相应的getter
、setter
办法和结构器。
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);
}
}
运转成果如下:
- 运用@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);
}
}
运转成果:
留意:假如在类中一同运用结构器注入和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
。
- 创立Bean和装备文件
创立一个新的Blue
类,其结构与White
类完全相同。然后在项目的resources
目录下创立一个新的blue.properties
文件,用于存储Blue
类的特点装备:
blue.title=blue-value-properties
blue.rank=2
- 引进装备文件
运用@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.properties
或application.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.properties
或application.yml
文件。咱们能够经过设置spring.config.name
和spring.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...
}
- Blue类的特点注入
关于properties
类型的特点,咱们这儿挑选@Value
注解和占位符来注入特点:
@Value("${blue.title}")
private String title;
@Value("${blue.rank}")
private Integer rank;
假如你熟悉jsp
的el
表达式,会发现这和它非常类似!
- 测试发动类
修正发动类,将装备类引进,然后取出并打印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);
}
}
运转成果如下:
- 引进外部装备文件@PropertySource
创立Blue
类和装备文件,没有setter
和getter
办法:
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);
}
}
运转成果如下:
- 在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);
}
}
运转成果如下:
4. SpEL表达式
当咱们谈到特点注入的时候,咱们可能会遇到一些杂乱的需求,例如咱们需求引证另一个Bean
的特点,或许咱们需求动态处理某个特点值。这种需求无法经过运用${}
的占位符办法完成,咱们需求一个更强壮的工具:SpEL
表达式。
Spring Expression Language
(SpEL
)是从Spring
结构 3.0
开端支撑的强壮工具。SpEL
不只是Spring
结构的重要组成部分,也能够独立运用。它的功用丰厚,包含调用特点值、特点参数、办法调用、数组存储以及逻辑计算等。它与开源项目OGNL
(Object-Graph Navigation Language
)类似,但SpEL
是Spring
结构推出的,并默许内嵌在Spring
结构中。
4.1 运用@Value注解和SpEL表达式完成特点注入
SpEL
的表达式用#{}
表明,花括号中便是咱们要编写的表达式。
咱们创立一个Bean
,命名为Azure
,相同地,咱们声明特点name
和priority
,并供给getter
和setter
办法以及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
特点直接仿制Azure
的name
特点,而priority
特点则期望比Azure
的priority
特点大1
,咱们能够这样编写:
@Component
public class Emerald {
@Value("#{'copy of ' + azure.name}")
private String name;
@Value("#{azure.priority + 1}")
private Integer priority;
}
在Spring
的SpEL
中能够经过bean
的称号拜访到对应的bean
,并经过.
操作符拜访bean
的特点。在这个例子中,azure
便是一个bean
的称号,它对应的bean
便是Azure
类的实例。所以,azure.name
便是拜访Azure
类实例的name
特点。
假如你在一个不涉及Spring
的环境中运用SpEL
,这个特性是不会生效的。这是由于这个特性依靠于Spring
的IoC
容器。
咱们修正发动类,测试运转,能够看到Azure
的特点现已成功被仿制:
use spel bean property : Emerald{name='copy of spel-for-azure', priority=11}
SpEL
表达式不只能够引证目标的特点,还能够直接引证类的常量,以及调用目标的办法。下面咱们经过示例进行演示。
咱们新建一个Bean
,命名为Ivory
。咱们依照上述办法初始化特点、toString()
办法、注解。
假设咱们有一个需求,让name
取azure
特点的前3
个字符,priority
取Integer
的最大值。那么咱们能够运用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
表达式特点注入的Bean
:Azure.java
、Emerald.java
和Ivory.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
, Emerald
和Ivory
,并经过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();
}
}
运转成果:
- 在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
需求运用#{}
,而不是${}
。
然后修正这3
个Bean
,假如是运用XML
来装备Spring
的Bean
的话,那么在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();
}
}
这样就能够在Spring
的XML
装备文件中运用SpEL
了。
运转成果如下:
欢迎一键三连~
有问题请留言,咱们一同讨论学习
———————-Talk is cheap, show me the code———————–