在 Java 中,监听类的属性值变化并在某些条件下执行特定操作,可以通过以下几种方式实现:
1. 使用 JavaBean 风格的 getter/setter 方法
可以通过 setter 方法来监听属性的变化,并在属性值被赋值时触发相关操作。通常情况下,这种方式是最常见且简单的方式。
示例:通过 setter 方法监听属性变化
public class MyClass {
private String name;
private int age;
// 监听属性变化的操作可以放在setter方法中
public void setName(String name) {
this.name = name;
// 监听 name 的变化
if ("Alice".equals(name)) {
doSomething();
}
}
public void setAge(int age) {
this.age = age;
// 监听 age 的变化
if (age > 30) {
doSomethingElse();
}
}
private void doSomething() {
System.out.println("Name is Alice, performing special action.");
}
private void doSomethingElse() {
System.out.println("Age is greater than 30, performing another action.");
}
}
2. 使用 PropertyChangeListener 监听属性变化
Java 提供了 PropertyChangeListener 接口,结合 PropertyChangeSupport 类可以用来监听属性变化。这种方式比直接使用 setter 方法更灵活,适用于需要在多个地方监听属性变化的场景。
示例:使用 PropertyChangeListener
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class MyClass {
private String name;
private int age;
private PropertyChangeSupport support;
public MyClass() {
support = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
// 通过 setter 方法设置属性并触发事件
public void setName(String name) {
String oldName = this.name;
this.name = name;
support.firePropertyChange("name", oldName, name);
}
public void setAge(int age) {
int oldAge = this.age;
this.age = age;
support.firePropertyChange("age", oldAge, age);
}
// 测试:触发监听器事件
public static void main(String[] args) {
MyClass myClass = new MyClass();
// 添加监听器
myClass.addPropertyChangeListener(evt -> {
if ("name".equals(evt.getPropertyName()) && "Alice".equals(evt.getNewValue())) {
System.out.println("Name is Alice, triggering special action.");
}
if ("age".equals(evt.getPropertyName()) && (int) evt.getNewValue() > 30) {
System.out.println("Age is greater than 30, triggering another action.");
}
});
// 修改属性,触发监听
myClass.setName("Alice");
myClass.setAge(35);
}
}
3. 使用 AOP(面向切面编程) 来监听属性变化
如果你想要更为通用的方案,避免在每个 setter 方法中手动写监听逻辑,可以通过 AOP (Aspect-Oriented Programming) 来实现。这种方式不依赖修改类内部的代码,可以在运行时通过切面来拦截属性的赋值过程。
示例:使用 AOP 监听属性变化
首先需要添加 AOP 依赖(如果你还没有添加的话):
<!-- Spring AOP 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后可以创建一个切面来监听属性值的变化:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class PropertyChangeAspect {
@Before("execution(void MyClass.setName(String)) && args(name)") // 监听 setName 方法
public void beforeNameChange(String name) {
if ("Alice".equals(name)) {
System.out.println("Name is Alice, performing special action.");
}
}
@Before("execution(void MyClass.setAge(int)) && args(age)") // 监听 setAge 方法
public void beforeAgeChange(int age) {
if (age > 30) {
System.out.println("Age is greater than 30, performing another action.");
}
}
}
4. 使用 监听器模式 (自定义事件)
你还可以实现一个更复杂的监听器模式,创建自己的事件和监听器,手动触发事件。
示例:自定义监听器模式
import java.util.ArrayList;
import java.util.List;
public class MyClass {
private String name;
private int age;
private List<NameChangeListener> nameListeners = new ArrayList<>();
private List<AgeChangeListener> ageListeners = new ArrayList<>();
// 添加监听器
public void addNameChangeListener(NameChangeListener listener) {
nameListeners.add(listener);
}
public void addAgeChangeListener(AgeChangeListener listener) {
ageListeners.add(listener);
}
// 触发监听事件
private void fireNameChangeEvent(String name) {
for (NameChangeListener listener : nameListeners) {
listener.onNameChanged(name);
}
}
private void fireAgeChangeEvent(int age) {
for (AgeChangeListener listener : ageListeners) {
listener.onAgeChanged(age);
}
}
// 通过 setter 方法设置属性
public void setName(String name) {
this.name = name;
fireNameChangeEvent(name);
}
public void setAge(int age) {
this.age = age;
fireAgeChangeEvent(age);
}
// 监听器接口
public interface NameChangeListener {
void onNameChanged(String name);
}
public interface AgeChangeListener {
void onAgeChanged(int age);
}
}
使用时可以添加具体的监听逻辑:
public class Main {
public static void main(String[] args) {
MyClass myClass = new MyClass();
// 添加名字变化监听器
myClass.addNameChangeListener(name -> {
if ("Alice".equals(name)) {
System.out.println("Name is Alice, special action triggered.");
}
});
// 添加年龄变化监听器
myClass.addAgeChangeListener(age -> {
if (age > 30) {
System.out.println("Age is greater than 30, action triggered.");
}
});
// 修改属性,触发监听器
myClass.setName("Alice");
myClass.setAge(35);
}
}
5. 总结
- 直接使用
setter方法:最简单的方式,直接在setter方法中添加条件判断并执行操作。 - 使用
PropertyChangeListener:适用于需要解耦属性变化监听逻辑的场景,可以将监听操作独立出来,使用PropertyChangeSupport来广播变化事件。 - 使用 AOP:最为灵活且解耦的方式,适合复杂场景,避免手动修改类的每个
setter方法。 - 自定义事件和监听器:适合需要自定义业务逻辑或多个监听器同时监听不同事件的情况。
根据需求选择合适的方式来实现类属性的监听和操作。
1124

被折叠的 条评论
为什么被折叠?



