Skip to content

示例中使用的类 (Classes Used in the Examples)

本节罗列了本章各示例中所使用的实体类。

Inventor

java
package org.spring.samples.spel.inventor;

import java.util.Date;
import java.util.GregorianCalendar;

public class Inventor {

	private String name;
	private String nationality;
	private String[] inventions;
	private Date birthdate;
	private PlaceOfBirth placeOfBirth;

	public Inventor(String name, String nationality) {
		GregorianCalendar c= new GregorianCalendar();
		this.name = name;
		this.nationality = nationality;
		this.birthdate = c.getTime();
	}

	public Inventor(String name, Date birthdate, String nationality) {
		this.name = name;
		this.nationality = nationality;
		this.birthdate = birthdate;
	}

	public Inventor() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNationality() {
		return nationality;
	}

	public void setNationality(String nationality) {
		this.nationality = nationality;
	}

	public Date getBirthdate() {
		return birthdate;
	}

	public void setBirthdate(Date birthdate) {
		this.birthdate = birthdate;
	}

	public PlaceOfBirth getPlaceOfBirth() {
		return placeOfBirth;
	}

	public void setPlaceOfBirth(PlaceOfBirth placeOfBirth) {
		this.placeOfBirth = placeOfBirth;
	}

	public void setInventions(String[] inventions) {
		this.inventions = inventions;
	}

	public String[] getInventions() {
		return inventions;
	}
}
kotlin
package org.spring.samples.spel.inventor

import java.util.*

class Inventor(
	var name: String,
	var nationality: String,
	var inventions: Array<String>? = null,
	var birthdate: Date =  GregorianCalendar().time,
	var placeOfBirth: PlaceOfBirth? = null)

PlaceOfBirth

java
package org.spring.samples.spel.inventor;

public class PlaceOfBirth {

	private String city;
	private String country;

	public PlaceOfBirth(String city) {
		this.city=city;
	}

	public PlaceOfBirth(String city, String country) {
		this(city);
		this.country = country;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String s) {
		this.city = s;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}
}
kotlin
package org.spring.samples.spel.inventor

class PlaceOfBirth(var city: String, var country: String? = null)

Society

java
package org.spring.samples.spel.inventor;

import java.util.*;

public class Society {

	private String name;

	public static String Advisors = "advisors";
	public static String President = "president";

	private List<Inventor> members = new ArrayList<>();
	private Map officers = new HashMap();

	public List getMembers() {
		return members;
	}

	public Map getOfficers() {
		return officers;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isMember(String name) {
		for (Inventor inventor : members) {
			if (inventor.getName().equals(name)) {
				return true;
			}
		}
		return false;
	}
}
kotlin
package org.spring.samples.spel.inventor

import java.util.*

class Society {

	val Advisors = "advisors"
	val President = "president"

	var name: String? = null

	val members = ArrayList<Inventor>()
	val officers = mapOf<Any, Any>()

	fun isMember(name: String): Boolean {
		for (inventor in members) {
			if (inventor.name == name) {
				return true
			}
		}
		return false
	}
}

补充教学

1. SpEL 是如何访问这些类的属性的?

SpEL 默认使用名为 StandardPropertyAccessor 的解析器。它遵循标准的 JavaBeans 命名规范

  • 当你写 placeOfBirth.city 时,SpEL 会尝试调用 getPlaceOfBirth(),接着在返回的对象上调用 getCity()
  • 如果属性是普通的 public 字段,SpEL 也会直接读取。

2. Kotlin 的互操作性细节

在示例中,你可以看到 Kotlin 代码非常简洁。

  • 属性映射:Kotlin 的 var name: String 会在字节码层面自动生成 getName()setName()。SpEL 在运行时能够无缝识别并调用这些生成的方法。
  • 默认参数:Kotlin 的默认参数(如 country: String? = null)极大简化了测试数据的构造,这在 SpEL 相关的单元测试中非常有用。

3. 数据类型映射建议

  • 日期处理:示例中使用了 java.util.Date。在现代 Spring (6+) 开发中,建议优先使用 java.time 包下的 LocalDateLocalDateTime。SpEL 同样完美支持 java.time 类型。
  • 泛型集合:虽然 Society 使用了 ArrayList<Inventor>,但 SpEL 在运行时由于 Java 的泛型擦除特性,其获取的仍然是 Object。SpEL 会根据实际运行时的对象类型动态分发方法调用。

4. 为什么这些类都在 Sample 包下?

在学习 SpEL 时,由于它经常涉及 T() 类型操作符和 new 操作符,显式的包路径(如 org.spring.samples.spel.inventor)对于理解 SpEL 的类型定位机制(Type Locator)至关重要。你需要在测试代码中确保这些类在 Classpath 路径下。

Based on Spring Framework.