如何获取类型为T的字段的类?
我为某些SpringMVC控制器编写JUnit测试。JUnit测试的初始化对于我的所有Controllers测试都是通用的,因此我想创建一个抽象类来执行此初始化。
因此,我创建了以下代码:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath*:spring/applicationContext-test.xml", "classpath*:spring/spring-mvc-test.xml" })
@Transactional
public abstract class AbstractSpringMVCControllerTest<T> {
@Autowired
protected ApplicationContext applicationContext;
protected MockHttpServletRequest request;
protected MockHttpServletResponse response;
protected HandlerAdapter handlerAdapter;
protected T controller;
@SuppressWarnings("unchecked")
@Before
public void initContext() throws SecurityException, NoSuchFieldException {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class);
// Does not work, the problem is here...
controller = applicationContext.getBean(T);
}
}
这个想法是为每个要测试扩展我的JUnit测试类的控制器创建一个AbstractSpringMVCControllerTest
。extends
声明中给出的类型是 的类。
例如,如果要测试我的AccountController
,我将创建AccountControllerTest
类似的类:
public class AccountControllerTest extends AbstractSpringMVCControllerTest<AccountController> { @Test
public void list_accounts() throws Exception {
request.setRequestURI("/account/list.html");
ModelAndView mav = handlerAdapter.handle(request, response, controller);
...
}
}
我的问题位于initContext()
抽象类方法的最后一行。这个抽象类将controller
对象声明为T
对象,但是如何对Spring
Application Context说返回类型的bean T
?
我已经尝试过类似的方法:
Class<?> controllerClass = this.getClass().getSuperclass().getDeclaredField("controller").getType(); controller = (T) applicationContext.getBean(controllerClass);
但controllerClass
返回java.lang.Object.class
类,而不是AccountController.class
。
当然,我可以创建一个public abstract Class<?> getControllerClass();
方法,每个JUnit
Controller测试类都将覆盖该方法,但我宁愿避免这种解决方案。
那么,有什么想法吗?
回答:
如果 您的AbstractSpringMVCControllerTest
bind 子类T
在编译时是可能的。也就是说,你有类似
public class DerpControllerTest extends AbstractSpringMVCControllerTest<DerpController> { }
而不是
public class AnyControllerTest<T> extends AbstractSpringMVCControllerTest<T> { }
我猜你可能是前者。在这种情况下,在运行时会T
从Class
对象中删除for
的类型AbstractSpringMVCControllerTest
,但是Class
for对象DerpControllerTest
确实
提供了一种方法来知道是什么T
,因为它是T
在编译时绑定的。
以下类演示如何访问的类型T
:
import java.lang.reflect.ParameterizedType;public abstract class Super<T> {
protected T object;
@SuppressWarnings("unchecked")
public Class<T> getObjectType() {
// This only works if the subclass directly subclasses this class
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
public class Sub extends Super<Double> {}
public class Test { public static void main(String...args) {
Sub s = new Sub();
System.out.println(s.getObjectType()); // prints "Class java.lang.Double"
}
}
以上是 如何获取类型为T的字段的类? 的全部内容, 来源链接: utcz.com/qa/422498.html