1

サービス クラスからデータを読み取るデータ テーブルを含むページがあります。そのサービス クラスは contactDAO で注入されると想定されていますが、すぐには注入されません。実際、ページが最初にロードされるとき、DAO がまだ挿入されていないため、データ テーブルは空です。ただし、addContact() を呼び出すと、それまでに contactDAO が挿入されるため、「連絡先」リストは正常に更新されます。

データテーブルがサービス クラスを使用する必要がある前に、contactDAO が確実に挿入されるようにするにはどうすればよいですか? Spring 3 と JSF 2.0 を使用しています。

データテーブルを含むページはリスト ' ' にバインドされていますcontactServiceImpl.contacts:

<h:dataTable var="contact" value="#{contactServiceImpl.contacts}">
...
</h:dataTable>

私の ContactServiceImpl は次のようになります。

@Service
public class ContactServiceImpl implements ContactService {

    private static List<Contact> contacts = new ArrayList<Contact>();

    @Autowired
    private static ContactDAO contactDAO;

    private ContactServiceImpl() {
        contacts = new ArrayList<Contact>();

        //TODO: need to inject contactDAO at the same time as instantiation
        contacts.clear();
        try {
            contacts.addAll( contactDAO.getContacts() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addContact(Contact contact) {
        contacts.add(contact);
        contactDAO.addContact(contact);

        contacts.clear();
        contacts.addAll( contactDAO.getContacts() );
    }

    @Autowired
    public void setContactDAO(ContactDAO contactDAO) {
        ContactServiceImpl.contactDAO = contactDAO;
        System.out.println("DAO is injected");
    }
}

そしてapplicationContext.xml

  <bean id="contactServiceImpl" class="com.example.service.ContactServiceImpl"
        scope="session">
        <property name="contactDAO" ref="contactDAOImpl"/>
  </bean>
4

1 に答える 1

1

Spring は、コンストラクターでプロパティを注入する前に常に Bean を作成するため、注入される前に注入されたプロパティを使用することはできません。この問題を解決するには、ロジックを書き直すか、contactDAO をコンストラクター引数として取得する必要があります (私は非常に醜い解決策を知っていますが、機能します)。

    private ContactServiceImpl(ContactDAO costrContactDAO) {
    contacts = new ArrayList<Contact>();

    //TODO: need to inject contactDAO at the same time as instantiation
    contacts.clear();
    try {
        contacts.addAll( costrContactDAO.getContacts() );
    } catch (Exception e) {
        e.printStackTrace();
    }
  }


  <bean id="contactServiceImpl" class="com.example.service.ContactServiceImpl"
    scope="session">
    <constructor-arg ref="contactDAOImpl"/>
    <property name="contactDAO" ref="contactDAOImpl"/>
  </bean>

他のソリューションを検索することを強くお勧めします (たとえば、私は自分のプロジェクトで Wicket を使用しています。テーブルをレンダリングする別の概念があります - DataProviders を使用するので、そのような問題はありません。JSF プロジェクトでこの概念を使用できるかもしれません)

于 2011-02-08T06:02:59.053 に答える