场景需求为:前台传来的对象种类不确定,根据不同的对象的对象种类id的传入,在同一个接口中,会调用不同的与对象相对应的service层及该service层内的方法。
举例两个种类分别为User和Student。
以枚举形势创建常量,保证了controller层调用不同service层的可扩展性和service层内方法的可扩展性:
public enum BeanEnum {
User(1,"userServiceImpl","findUser"),
Student(2,"studentServiceImpl","findStudent");
private Integer beanType;
private String className;
private String methodName;
BeanEnum(Integer beanType, String className, String methodName) {
this.beanType = beanType;
this.className = className;
this.methodName = methodName;
}
public static BeanConfig getBeanConfig(Integer beanType){
BeanConfig beanConfig = new BeanConfig();
for (BeanEnum singleBE : BeanEnum.values()) {
if (singleBE.beanType.equals(beanType)) {
beanConfig.setClassName(singleBE.className);
beanConfig.setMethodName(singleBE.methodName);
}
}
return beanConfig;
}
}
下面注意:在获取service层实例对象时,如果利用className直接反射获取字节码对象,然后newInstance获取实例对象,这个实例对象是与springIOC容器无关的,因此无法在该对象中,也就是userServiceImpl/studentServiceImpl中执行@Autowired注入dao层数据,所以需要直接在springIOC容器中获取实例对象,并反向获取其字节码对象,用于反射执行该实例对象内的方法。
代码如下:
@Service
public class BeanServiceImpl implements BeanService {
/**
* 获取对象实例
* @param beanType 对象种类
* @param beanId 对象id
* @return
*/
public Object findObj(Integer beanType,Integer beanId){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext-*.xml");
BeanConfig beanConfig = BeanEnum.getBeanConfig(beanType);
String className = beanConfig.getClassName();
String methodName = beanConfig.getMethodName();
try {
Object o = applicationContext.getBean(className);
Class<?> clazz = o.getClass();
Method m = clazz.getDeclaredMethod(methodName, Integer.class);
m.setAccessible(true);
Object obj = m.invoke(o, beanId);
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
版权声明:本文为u011798348原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。