2012-07-09 29 views
17

これはHibernateを使用したSpring MVCプロジェクトです。 私は、データベースへのログの入力を担当するLoggerクラスを作成しようとしています。 他のクラスは、いくつかの属性を持つ適切なメソッドを呼び出すだけで、このクラスはすべての魔法を実行する必要があります。 性質上、静的メソッドを持つクラスである必要がありますが、autowiering DAOオブジェクトで問題が発生します。静的クラスでの自動入力

public class StatisticLogger { 
    @Autowired 
    static Dao dao; 
    public static void AddLoginEvent(LogStatisticBean user){ 
     //TODO code it god damn it 
    } 
    public static void AddDocumentEvent(LogStatisticBean user, Document document, DocumentActionFlags actionPerformed){ 
     //TODO code it god damn it 
    } 
    public static void addErrorLog(Exception e, String page, HashMap<String, Object> parameters){ 
     ExceptionLogBean elb=new ExceptionLogBean(); 
     elb.setStuntDescription(e); 
     elb.setSourcePage(page); 
     elb.setParameters(parameters); 
     if(dao!=null){ //BUT DAO IS NULL 
      dao.saveOrUpdateEntity(elb); 
    } 
} 

正しく行うには? DAOオブジェクトをnullにしないためにはどうすればよいですか? メソッドのパラメータとして渡すことができますが、あまり良くありません。 私はautowieringメカニズムがまだ作成されていないために作成されているので、autowiredは静的オブジェクトでは動作しないと推測しています。

答えて

38

静的フィールドは@Autowiredできません。一言、@Autowiredインスタンスフィールドで

@Component 
public class StatisticLogger { 

    private static Dao dao; 

    @Autowired 
    private Dao dao0; 

    @PostConstruct  
    private void initStaticDao() { 
    dao = this.dao0; 
    } 

} 

を、そしてあなたのオブジェクトが構築されたときに提出された静的に値を割り当てます。しかし、これに対処するためのトリッキーなスキルがあります。ところで、StatisticLoggerオブジェクトはSpringでも管理する必要があります。

+0

興味深いありがとうトリック。私は将来を考えています:) –

+0

メソッドの戻り値の型は無効でなければなりません。 http://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html –

+1

戦闘の後、私は大部分の場合に機能するこのソリューションを使用するようになりました。しかし、Sonar社はすぐに私に警告してくれました。「非静的メソッドから静的フィールドを正しく更新するのは難しいです。複数のクラスインスタンスや複数のスレッドがある場合、バグにつながる可能性があります。理想的には、静的フィールドは同期された静的メソッドからのみ更新されます.'私はそれに言及する価値があると思いました。 – MaxouMask

14

静的クラスはBeanではないため、Springで管理することができないため、古典的なautowiringはおそらく動作しません。例えばthe factory-method aproach in XMLを使ったり、静的イニシャライザブロックのSpringコンテキストからBeanを読み込んだりするなどの方法がありますが、あなたのデザインを変更することをお勧めします。

静的メソッドを使わないでください。必要な場所に注入するサービスを使用します。 Springを使用する場合は、Springを正しく使用することもできます。 Dependency Injectionはオブジェクト指向のテクニックであり、実際にOOPを採用している場合にのみ意味があります。

+0

ニース、 –

0

私はこれが古い質問です知っているが、ちょうど私が何をしたか共有したいと思った、@Weiboリーによって ソリューションはokですが、問題は、それが静的変数

に非静的変数を割り当てることについてソナー重要なアラートを生成しますノーソナーの警告とそれを解決する方法は、私はStatisticLoggerは(もはや静的)クラスをsingltonするために変更するには、次

  1. あるこの

    パブリッククラスStatistiよう cLogger { プライベート静的StatisticLoggerインスタンス= null; プライベートDaoダオ;私はこの春に、それは前に、すべての管理対象Beanを初期化しますので、安全でありたいとsingltonクラス でそれを設定したサービスをautowireサービス(またはコンポーネント)を作成し

  2. public static StatisticLogger getInstance() { 
        if (instance == null) { 
         instance = new StatisticLogger(); 
        } 
        return instance; 
    } 
    
    protected StatisticLogger() { 
    } 
    
    public void setDao(Dao dao) { 
        this.dao = dao; 
    } 
    public void AddLoginEvent(LogStatisticBean user){ 
        //TODO code it god damn it 
    } 
    public void AddDocumentEvent(LogStatisticBean user, Document document, DocumentActionFlags actionPerformed){ 
        //TODO code it god damn it 
    } 
    public void addErrorLog(Exception e, String page, HashMap<String, Object> parameters){ 
        ExceptionLogBean elb=new ExceptionLogBean(); 
        elb.setStuntDescription(e); 
        elb.setSourcePage(page); 
        elb.setParameters(parameters); 
        if(dao!=null){ 
         dao.saveOrUpdateEntity(elb); 
    } 
    

    }何かをやって、それは何かがこの

    @Component パブリッククラスDaoSetterServiceようStatisticLogger 何かにアクセスする前に、以下のPostConstructメソッドが常に呼び出されるわけ{

    @Autowired 
    private Dao dao0; 
    
    @PostConstruct  
    private void setDaoValue() { 
        StatisticLogger.getInstance().setDao(dao0); 
    } 
    

    }

  3. 代わりの静的なクラスとしてStatisticLoggerを使用して、私はちょうどStatisticLogger.getInstance(としてそれを使用)し、私はその中のすべてのメソッドにアクセスすることができます

関連する問題