Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否要将内部类@Inject/@Autowire连接到外部类?_Java_Spring_Dependency Injection - Fatal编程技术网

Java 是否要将内部类@Inject/@Autowire连接到外部类?

Java 是否要将内部类@Inject/@Autowire连接到外部类?,java,spring,dependency-injection,Java,Spring,Dependency Injection,在Spring/JSR-330中,有没有一种方法可以正确地声明一个需要依赖注入的内部类,这样我就可以将它注入到外部类中 <mvc:annotation-driven conversion-service="applicationConversionService" > <mvc:argument-resolvers> <bean class="org.springframework.security.web.bind.support.Authentica

在Spring/JSR-330中,有没有一种方法可以正确地声明一个需要依赖注入的内部类,这样我就可以将它注入到外部类中

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
例如:

@Component
public class TestClass{

    // How to declare this class?
    private class TestClassInner{
       @Autowired private SomeBean somebean;

       public boolean doSomeWork(){
          return somebean.doSomething();
       }               
    }

    // Inject the inner class here in the outer class such that the outer class can use an instance of it
    @Autowired TestClassInner innerClass;

    @PostConstruct
    public void init(){
        ...
    }

    public void someMethod(){
       innerClass.doSomeWork();
       ...
    }
}
<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
我尝试过用@Component注释内部类,使其成为公共类,使其成为公共静态类,等等,但似乎我尝试过的每一个组合最终都会抛出一个或另一个错误

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
作为一个私有内部类,Spring抱怨它缺少构造函数,即使我定义了一个构造函数

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
作为一个带注释的
@组件
公共静态类,Spring抱怨它发现了两个bean-TestClass@TestClassInner和testClass.TestClassInner。如果我使用
@限定符
,它就会抱怨找不到bean

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
我想我误解了这些内部bean如何工作/与Spring交互,从而正确理解是否/如何声明它们

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
这可能吗

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
编辑

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
下面是我尝试过的几个组合(包括尝试基于@SotiriosDelimanolis响应实现一个新的构造函数):

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
抛出错误(公共和私有内部类都抛出相同的错误):

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
编辑2

@Controller
public class ContractController {

    @Component
    static public class InnerClass extends AttachmentControllerSupport{

        /**
         * 
         */
        public InnerClass() {
            super();
            // TODO Auto-generated constructor stub
        }

        public InnerClass( ContractController c){
            super();
        }
    }

    @Autowired private InnerClass innerclass;

    @Autowired private AttachmentControllerSupport attachmentControllerSupport;
    @Autowired private ContractService contractService;

}
<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
applicationContext.xml:

<context:component-scan base-package="com.ia">
    <context:exclude-filter expression=".*_Roo_.*" type="regex"/>
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<context:spring-configured/>
<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>

restmvc-config.xml:

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>

可以通过
@Component
注释声明和实例化内部类bean,但解决方案很难看,但我稍后会讨论。首先,这里介绍如何使用XML中的
声明。给定

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
package com.example;

public class Example {
    @Autowired
    private Inner inner;
    public class Inner {        
    }
}
你会的

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
<bean name="ex" class="com.example.Example" />
<bean name="inner" class="com.example.Example$Inner">
    <constructor-arg ref="ex"></constructor-arg>
</bean>
上述内容实际上将被编译为

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
public Inner (Example enclosingInstance) {}
对于Java代码,该参数的参数隐式地与语法一起提供

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
enclosingInstance.new Inner();
Spring使用反射来实例化bean类并初始化bean。这里描述的概念也适用于反射。用于初始化
内部
类的
构造函数
的第一个参数必须是封闭类的类型。这就是我们在这里通过声明一个
构造函数arg
明确地做的事情

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
使用
@组件的解决方案取决于以下几点。首先,你必须知道上面讨论的所有事情。基本上,对于
构造函数
对象,当调用
newInstance()
时,需要传递封闭类的实例作为第一个参数。其次,您必须知道Spring如何处理注释。当被注释的类有一个用
@Autowired
注释的构造函数时,它将选择该构造函数来初始化bean。它还使用
ApplicationContext
解析要作为参数注入构造函数的bean

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
根据这两个事实,您可以编写这样的类

<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>
@Component
public class Example {
    @Component
    public class Inner {
        @Autowired
        public Inner() {}

    }
}

在这里,我们的内部类有一个
@Autowired
构造函数,因此Spring确切地知道要使用哪个
构造函数。由于
@Autowired
的原因,它还将尝试从
ApplicationContext
中找到一个bean,以匹配并注入构造函数具有的每个参数。在本例中,唯一的参数类型为
Example
,即封闭类。由于
示例
也用
@Component
注释,因此它也是上下文中的一个bean,因此Spring可以将它注入到内部类的构造函数中。

答案看起来很有趣。我肯定地知道
@Configuration
可以做到这一点,如果这是特定于构造型的,我会感到惊讶。@chrylisby
@Configuration
你是说用
@Bean
方法显式创建一个内部类instance吗?对不起,我不太清楚。我的意思是,我经常使用带有
@Configuration
注释的嵌套(但静态,而不是内部)类,没有任何问题。@chrylis这就是嵌套(静态)与内部的全部区别。嵌套类只是普通类。内部类引用了一个封闭的实例。对于初学者来说,您不正确的术语混淆了一个本身就足够复杂的问题。在Java中,“内部类”是一个非静态嵌套类;嵌套类可以是内部的,也可以是静态的。@chrylis我实际上没有意识到这一点。谢谢你的澄清。我在这里使用术语“内部类”来指嵌套类。我会试着在编辑这篇文章时牢记这一点
<mvc:annotation-driven conversion-service="applicationConversionService" >
  <mvc:argument-resolvers>
    <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver" />
  </mvc:argument-resolvers>
</mvc:annotation-driven>