使用前提:
当前类首先要获取spring 的 applicationContext 对象(环境需要是 springframework 框架),然后在项目启动时执行 applicationContext.getBeansOfType 以获取我们目标接口下的所有实现类,然后执行我们后续的其他操作。
下面就开始使用,首先创建一个实体类,用来做类型
package com.app.service.studentTest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName Student
* @Description 实体
* @Author houbing
* @Date 2023/7/13 10:04
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private String sex;
private Integer age;
}
再创建一个枚举类,用来获取IStudent接口对应value的实现类
package com.app.service.studentTest;
/**
* @ClassName ReportEnum
* @Description 枚举类,用来获取IStudent接口对应value的实现类
* @Author houbing
* @Date 2023/7/13 10:08
*/
public enum ReportEnum {
QJ_USER_CASH("QjUserCash", "客户"),
XH_TABLE("XhTable", "日报"),
XH_YB_TABLE("XhYbTable", "月报"),
XH_YB_PUBLIC("XhYbPublic", "持仓表");
private final String value;
private final String desc;
ReportEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
之后创建一个接口,里面写上方法,并写一个枚举类的方法
package com.app.service.studentTest;
/**
* @ClassName Student
* @Description 接口
* @Author houbing
* @Date 2023/7/13 10:02
*/
public interface IStudent {
Student go();
//枚举类的方法
ReportEnum actionName();
}
创建四个实现类来实现这个接口
第一个实现类
package com.app.service.studentTest;
/**
* @ClassName Student1
* @Description 实现类1
* @Author houbing
* @Date 2023/7/13 10:11
*/
public class Student1 implements IStudent{
public Student go() {
return new Student("zhangsan","nan",5);
}
//返回枚举的类型
public ReportEnum actionName() {
return ReportEnum.QJ_USER_CASH;
}
}
第二个实现类
package com.app.service.studentTest;
import org.springframework.stereotype.Component;
/**
* @ClassName Student2
* @Description 实现类2
* @Author houbing
* @Date 2023/7/13 10:12
*/
@Component
public class Student2 implements IStudent{
@Override
public Student go() {
return new Student("lisi","nv",9);
}
//返回枚举的类型
@Override
public ReportEnum actionName() {
return ReportEnum.XH_TABLE;
}
}
第三个实现类
package com.app.service.studentTest;
import org.springframework.stereotype.Component;
/**
* @ClassName Student3
* @Description 实现类3
* @Author houbing
* @Date 2023/7/13 10:13
*/
@Component
public class Student3 implements IStudent {
@Override
public Student go() {
return new Student("wangwu","nan",15);
}
//返回枚举的类型
@Override
public ReportEnum actionName() {
return ReportEnum.XH_YB_TABLE;
}
}
第四个实现类
package com.app.service.studentTest;
import org.springframework.stereotype.Component;
/**
* @ClassName Student4
* @Description 实现类4
* @Author houbing
* @Date 2023/7/13 10:14
*/
@Component
public class Student4 implements IStudent{
@Override
public Student go() {
return new Student("xiexun","nan",58);
}
//返回枚举的类型
@Override
public ReportEnum actionName() {
return ReportEnum.XH_YB_PUBLIC;
}
}
开始使用applicationContext.getBeansOfType方法,该类要去实现spring框架的ApplicationContextAware接口,获取ApplicationContext上下文,可以进行对业务模块的书写,调用对应的接口实现类进行业务逻辑实现
package com.app.service.studentTest;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
/**
* @ClassName StudentTest
* @Description TODO
* @Author houbing
* @Date 2023/7/13 16:16
*/
public class StudentTest implements ApplicationContextAware {
private ApplicationContext applicationContext;
Map<ReportEnum, IStudent> map = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@PostConstruct //@PostConstruct注解的方法在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,
// 可作为一些数据的常规化加载,比如数据字典之类的。
private void init(){
//applicationContext.getBeansOfType 以获取我们目标接口下的所有实现类
Map<String, IStudent> studentMap = applicationContext.getBeansOfType(IStudent.class);
// 这里的结果返回 即为多个实现的子类,然后组成一个迭代器
Iterator<IStudent> iterator = studentMap.values().iterator();
while (iterator.hasNext()){
//获取每一个实现类
IStudent student = iterator.next();
//用枚举类里面的枚举作为map的键,值为实现类(这样的话,现在map集合里面已经有四个值)
map.put(student.actionName(),student);
}
}
//调用这个方法,就可以使用这个接口里面定义的方法,具体如下注解
public IStudent getStudent(ReportEnum reportEnum){
//调用这个方法的时候,根据具体的枚举获取对应的实体类
// 在调用iStudent接口方法的时候,这时调用的就是枚举对应的实体类的方法
IStudent iStudent = map.get(reportEnum);
if (Objects.isNull(iStudent)){
System.out.println("不能为空");
throw new NullPointerException();
}
return iStudent;
}
}