@SearchType("guide")
进行标记Map
search-system-springboot/
├── SearchSystemApplication.java
├── annotation/
│ └── SearchType.java
├── strategy/
│ ├── SearchStrategy.java
│ ├── GuideSearch.java
│ ├── ExpertSearch.java
│ ├── TravelNoteSearch.java
│ └── SearchStrategyFactory.java
└── controller/
└── SearchController.java
SearchStrategy.java
(策略接口)package strategy;
public interface SearchStrategy {
void search(String keyword);
}
@SearchType
注解(用于标记策略类型)package annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SearchType {
String value(); // 类型名称,如 "guide"
}
SearchStrategyFactory.java
(策略注册器)package strategy;
import annotation.SearchType;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class SearchStrategyFactory {
@Autowired
private ApplicationContext context;
private final Map<String, SearchStrategy> strategyMap = new HashMap<>();
@PostConstruct
public void init() {
Map<String, Object> beans = context.getBeansWithAnnotation(SearchType.class);
for (Object bean : beans.values()) {
Class<?> clazz = bean.getClass();
SearchType annotation = clazz.getAnnotation(SearchType.class);
String type = annotation.value().toLowerCase();
strategyMap.put(type, (SearchStrategy) bean);
}
}
public SearchStrategy getStrategy(String type) {
SearchStrategy strategy = strategyMap.get(type.toLowerCase());
if (strategy == null) {
throw new IllegalArgumentException("不支持的搜索类型: " + type);
}
return strategy;
}
}
GuideSearch.java
package strategy;
import annotation.SearchType;
import org.springframework.stereotype.Component;
@Component
@SearchType("guide")
public class GuideSearch implements SearchStrategy {
public void search(String keyword) {
System.out.println("搜索攻略:" + keyword);
}
}
ExpertSearch.java
package strategy;
import annotation.SearchType;
import org.springframework.stereotype.Component;
@Component
@SearchType("expert")
public class ExpertSearch implements SearchStrategy {
public void search(String keyword) {
System.out.println("搜索达人:" + keyword);
}
}
SearchController.java
package controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import strategy.SearchStrategy;
import strategy.SearchStrategyFactory;
@RestController
@RequestMapping("/search")
public class SearchController {
@Autowired
private SearchStrategyFactory factory;
@GetMapping
public String search(@RequestParam String type, @RequestParam String keyword) {
SearchStrategy strategy = factory.getStrategy(type);
strategy.search(keyword);
return "搜索成功:" + type + " -> " + keyword;
}
}
SearchSystemApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SearchSystemApplication {
public static void main(String[] args) {
SpringApplication.run(SearchSystemApplication.class, args);
}
}
annotation
、strategy
、controller
)http://localhost:8080/search?type=guide&keyword=台北夜市
输出:
搜索攻略:台北夜市
比如新增 TravelNoteSearch
:
@Component
@SearchType("travelnote")
public class TravelNoteSearch implements SearchStrategy {
public void search(String keyword) {
System.out.println("搜索游记:" + keyword);
}
}
就完事了,无需改动任何已有类!开闭原则 ✔️