10

自動配線注釈に問題があります。私のアプリは次のようになります。

これがコントローラーです:

@Controller
public class MyController {
    @Autowired
    @Qualifier("someService")
    private SomeService someService;

    ....
}

これはサービスレイヤーです。

public interface SomeService {
    ...
}

@Service
public class SomeServiceImpl implements SomeService{    
    @Autowired
    @Qualifier("myDAO")
    private MyDAO myDAO;

    ....
}

そしてDAOレイヤー:

public interface MyDAO{
    ....        
}

@Repository
public class JDBCDAOImpl implements MyDAO {    
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;    
    ....
}

これはapp-service.xmlファイルです。

....
<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
      p:location="/WEB-INF/jdbc.properties" />

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="${jdbc.driverClassName}"
      p:url="${jdbc.url}"
      p:username="${jdbc.username}"
      p:password="${jdbc.password}"/>

<bean id="SomeService" class="com.service.SomeServiceImpl" />    
<bean id="myDAO" class="com.db.JDBCDAOImpl" />    

だから...私がウェブアプリを起動しているとき、MyController Autowiresは正しく(someServiceImplクラスオブジェクトによって正しく注入されたsomeServiceフィールド)、しかしsomeServiceのmyDAOフィールドはnull値を持っています(正しく注入されていません)。

問題を見つけるのを手伝ってもらえますか?

PS興味深いですが、「Bean ID」をmyDAOから別のID(myDAO2など)に変更すると、Bean myDAOが存在しないため、システムから注入が実行できなかったというエラーが表示されます。それで、春は注射をします、しかしそれはどこにありますか?そして、なぜそれが正しく機能しないのですか?

4

7 に答える 7

13

私は解決策を見つけました。Javiが言ったように(Javiさん、どうもありがとうございました)、DAOおよびServiceレイヤークラスに注釈を付ける必要があり@Repositoryます@Service。今、私はこのように書こうとしました:

@Service("someService")
public class SomeServiceImpl implements SomeService{    
    @Autowired
    @Qualifier("myDAO")
    private MyDAO myDAO;

    ....
}

@Repository("myDAO")
    public class JDBCDAOImpl implements MyDAO {    
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;    
    ....
}

そして、すべてが正常に動作します!!!

しかし、私はまだこの質問に対する答えを見つけられませんでした:アプリケーションがより複雑になり、より複雑な構造になる場合@Repositore@Service一部のクラスではアノテーションが好ましくない場合、下位レベル(フィールド内)にあるBeanを正しく注入する方法クラスの、またはクラスのフィールドのフィールドで)(@Autowireもちろん注釈付き)?

于 2010-11-26T19:21:57.767 に答える
4

私はあなたが必要だと思います<context:annotation-config />

于 2010-11-26T18:59:29.703 に答える
3

使用できます

<context:component-scan base-package="PATH OF THE BASE PACKAGE"/>  

構成.xmlファイルのエントリ。このエントリは、Javaクラスから指定されたすべてのタイプとアノテーションをスキャン/読み取ります。

于 2013-09-23T09:11:25.083 に答える
1

重要なポイント:

  1. @Componentは、デフォルトのコンストラクターが見つからないと言う問題を引き起こす場合があります。@Componentアノテーションとして定義されているクラスには、デフォルトのコンストラクターが必要です。
  2. ユーザー定義のクラス参照であるフィールドに@Autowiredアノテーションを適用したとします。ここで、@ Componentもそのクラスに適用すると、常にnullで初期化されます。したがって、@ Autowiredを含むフィールドでは、クラス定義に@Componentを含めることはできません。
  3. デフォルトでは、@AutowiredはbyTypeです。

アドレスBeanはStudentクラスで自動配線されます。Address.javaで@Componentを適用するとどうなるか見てみましょう。

CollegeApp.java:

package com.myTest
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.bean.Address;
import com.bean.Student;
//Component scanning will for only those classes
//which is defined as @Component. But, all the class should not use
//@Component always even if the class is enabled with auto
//component scanning, specially the class which is Autowired
//Or which is a property of another class 
@Configuration
@ComponentScan(basePackages={"com.bean"})
public class CollegeApp {
    @Bean
    public Address getAddress(){
        return new Address("Elgin street");
}
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(CollegeApp.class);
        Student student=context.getBean(Student.class);
        System.out.println(student.toString());
        context.close();
    }
}

Elgin通りを学生の住所で自動配線する必要があります。

Address.java:

package com.bean;
import org.springframework.stereotype.Component;
@Component
public class Address {
    private String street;
    public Address()
    {
    }
    public Address(String theStreet)
    {
        street=theStreet;
    }
    public String toString()
    {
        return (" Address:"+street);
    }
}

Student.java:

package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Student {
    private String name;
    private int age;
    private Address address;
    public Student()
    {
    }
    public Student(String theName,int theAge)
    {
        name=theName;age=theAge;
    }
    @Autowired
    public void setAddress(Address address) {
        this.address = address;
    }
    public String toString()
    {
        return ("Name:"+name+" Age:"+age+ " "+address);
    }
}

出力:-Name:null Age:0 Address:null//アドレスはここで自動配線されていません。

この問題を解決するには、Address.javaを次のように変更するだけです。

Address.java:

package com.bean;
public class Address {
    private String street;
    public Address(String theStreet)
    {
        street=theStreet;
    }
    public String toString()
    {
        return (" Address:"+street);
    }
}

出力:-名前:null年齢:0住所:Elginstreet

于 2018-08-08T16:57:41.060 に答える
0

XMLコードのこのセクションを次の場所に含める必要がありますspring-config.xml

<context:component-scan base-package="Fully.Qualified.Package.Name" />

しかし、ほとんどの人がこれら2つを提案しているので、 <context:annotation-config>vsの違いを知っておく必要があります。<context:component-scan>

1)両方のタグの最初の大きな違い<context:annotation-config>は、アプリケーションコンテキストですでに登録されているBeanに適用されたアノテーションをアクティブ化するために使用されることです。Beanがどのメカニズムによって登録されたか(たとえば、を使用して登録されたか、ファイル自体<context:component-scan>で定義されたかは関係ありません)。application-context.xml

2)2番目の違いは、最初の違い自体から生じます。Beanをコンテキストに登録し、Bean内の注釈をスキャンしてアクティブ化します。だから<context:component-scan>; 何をするか<context:annotation-config>を実行しますが、さらにパッケージをスキャンしてBeanをアプリケーションコンテキストに登録します。

于 2020-03-29T18:23:19.097 に答える
0

これには2つの理由が考えられます。

  1. 挿入されたオブジェクトに注釈を付けていない場合、または適切な@ Service / @ Component /@Repository注釈を付けてserviceと言っている場合。

  2. ポイント1を確認したら、次に、アノテーション付きサービスクラスのクラスパッケージがメインクラスのスプリングブートアプリケーションのクラスパスに含まれているかどうかを確認します。これは、次のアノテーションを使用して構成できます。

@SpringBootApplication(scanBasePackages = {"com.ie.efgh.somepackage"、 "com.ie.abcd.someotherpackage"})

これを行うと、クラスのロード中にクラスのパッケージを調べるようにSpringに指示します。

于 2020-12-17T13:49:06.130 に答える
-2
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Specifying base package of the Components like Controller, Service, 
        DAO -->
    <context:component-scan base-package="com.jwt" />

    <!-- Getting Database properties -->
    <context:property-placeholder location="classpath:application.properties" />

    <!-- DataSource -->
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        id="dataSource">
        <property name="driverClassName" value="${database.driver}"></property>
        <property name="url" value="${database.url}"></property>
        <property name="username" value="${database.user}"></property>
        <property name="password" value="${database.password}"></property>
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
    </bean>

</beans>
于 2018-04-13T09:56:43.697 に答える