我在Spring Controller中使用内部类。从它的父类超类中访问受保护的字段/方法时遇到了问题。
研究表明,这是由不同的类加载器引起的,但我对Spring的了解不够充分。
class SuperBaseController {
protected String aField;
protected void aMethod() {
}
}
@Controller
class OuterMyController extends SuperBaseController {
class Inner {
public void itsMethod() {
// java.lang.IllegalAccessError: tried to access method
aMethod();
}
public void getField() {
// java.lang.IllegalAccessError: tried to access field
String s = aField;
}
}
void doSomething () {
// Obviously fine.
aMethod();
// Fails in the Inner method call.
new Inner().itsMethod();
// Obviously fine.
String s = aField;
// Fails in the Inner method call.
new Inner().getField();
}
}
是否有任何简单的技巧可以避免/解决此问题?最好不涉及制作字段/方法public
。
我已经确认外部类的ClassLoader
属性与超类的属性不同。
答案 0 :(得分:0)
我创建了以下类:
public class BaseController
{
protected String field;
protected void method()
{
System.out.println("I'm protected method");
}
}
@RestController
@RequestMapping("/stack")
public class StackController extends BaseController
{
class Inner
{
public void methodInvocation()
{
method();
}
public void fieldInvocation()
{
field = "Test";
}
}
@RequestMapping(value= {"/invoca"}, method= {RequestMethod.GET})
public ResponseEntity<String> invocation()
{
Inner in = new Inner();
in.fieldInvocation();
in.methodInvocation();
return new ResponseEntity<String>("OK", HttpStatus.OK);
}
}
我试图调用其余的服务而且没有问题。现在我将这个配置用于Spring(基于注释的注释):
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = { "it.spring.controller" })
@PropertySource( value={"classpath:config.properties"}, encoding="UTF-8", ignoreResourceNotFound=false)
public class DbConfig
{
}
@Configuration
@EnableWebMvc
@Import(DbConfig.class)
@PropertySource(value = { "classpath:config.properties" }, encoding = "UTF-8", ignoreResourceNotFound = false)
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
}
正如您所看到的,我使用了@Import
注释,并在我的web.xml中使用了此配置:
<servlet>
<servlet-name>SpringDispSvlt</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>it.WebMvcConfig</param-value>
</init-param>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
通过使用此配置,我在调用内部类
中的受保护字段和/或方法时没有任何问题如果你无法使你的配置适应这个..你可以发布你使用的配置吗?
我希望它有用
安吉洛
答案 1 :(得分:0)
怎么样:
class OuterMyController extends SuperBaseController {
private String getAField() { return super.aField; }
protected void aMethod() { super.aMethod(); }
...
}
现在内部类使用其外部类的方法,因此没有非法访问,外部类的方法可以访问基类的受保护字段。
答案 2 :(得分:0)
class SuperBaseController {
protected String aField;
protected void aMethod() {
}
}
@Controller
class OuterMyController extends SuperBaseController {
public void itsMethod() {
aMethod();
}
public void getField() {
String s = aField;
}
class Inner {
public void innerItsMethod() {
itsMethod();
}
public void innerGetField() {
String s = getField();
}
}
void doSomething () {
aMethod();
new Inner().itsMethod();
String s = aField;
new Inner().getField();
}
}
这有用吗?
此外,您可能必须定义运行该方法的对象。 (例如Inner.getField()或SuperBaseController.aMethod())