12

私はSpring IOCのコンセプトを始めたばかりです。インターネットで見つかったほとんどの例では、コードを使用してオブジェクトを取得することがよくあります。

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) appContext.getBean("hello"); 

stackoverflow のこれらの質問1および2からの参照として。私は、悪い習慣と見なされるコードで appContext.getBean("hello") を使用する必要はないと推測しました。また、推奨されなくなりました。私の推論が間違っている場合は、ここで訂正してください。

それを考慮して、それに応じてプロジェクトに変更を加えました。これが私のapplicationContext.xmlです

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="utilClassRef" class="org.hd.derbyops.DUtils" lazy-init="false" />
<bean id="appContext" class="org.hd.derbyops.ContextProvider" lazy-init="false">
   <property name="utils" ref="utilClassRef" />
</bean>
</beans>

私のcontextProviderクラスコード

public class ContextProvider implements ApplicationContextAware {

    private static ApplicationContext ctx;

    /**
     * Objects as properties
     */
    private static DUtils utils;

    public void setApplicationContext(ApplicationContext appContext)
            throws BeansException {
        ctx = appContext;

    }

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }

    public static DUtils getUtils() {
        return utils;
    }

    public void setUtils(DUtils dUtilsRef) {
        utils = dUtilsRef;
    }

}

たとえば、org.hd.derbyops.DUtils に依存するクラス A を考えてみましょう。次のコード行を使用しています

ContextProvider.getUtils();

クラスAでDUtilsオブジェクトを取得するため ApplicationContext.getBean()、コード内のどこでも使用できなくなります。

10 個のクラスがあり、クラス A がそれらすべてに依存しており、そのオブジェクトが を使用せずに作成およびアクセスされるとしますApplicationContext.getBean()。その場合も、上記のように、ContextProvider クラスのプロパティを作成し、その後にそのプロパティのセッターとゲッターを作成することを考えています。ここで、inget<PropertyName>は静的です。そのため、このように、オブジェクトが必要な場所ならどこでも使用できます

ContextProvider.get<PropertyName>;

これが私の簡単な質問です。まず、私のアプローチは正しいですか?もしそうなら、起動時にすべての Bean をロードすると、パフォーマンス キラーになりませんか? getBean を少なくとも 2 回以上呼び出すことなく、アプリケーションでそれを行うにはどうすればよいでしょうか?

Web アプリケーションを設計しApplicationContext.getBean()、コードを使用せずに Spring IOC を実装する場合。どうやってそれをしますか?

注:上記でタグ付けされた他の質問を参照してください。

ApplicationContext.getBean() の呼び出しは制御の反転ではありません!

4

2 に答える 2

9

簡単な答えは、「はい」と「いいえ」、「いいえ」、「いいえ」です。そして最後に、春のMVCをオンラインで検索します。これは、おそらくあなたが望むことを実行するからです。

だから、あなたのアプローチ。はい、あなたはそれのほとんどを正しく持っています。ただし、すべてに静的メソッドを使用することは非常に悪い習慣と見なされます。そして、あなたはそうする必要はありません。Springは、通常のpojoを簡単に作成でき、Springはそれらをシングルトンとして使用し、相互に注入するという考えに基づいています(オブジェクトをその場で作成することもできますが、ここでは一般的なケースを取り上げます)。静的クラスとメソッドを使用する場合は、次のようにします。

  • ユニットテストのためにそれらをモックすることはできません(JUnitを使用していますか?)
  • 継承して使用することはできません
  • 静的イニシャライザーは、例外をなくすための優れた方法です
  • などなど

したがって、インジェクションには「はい」、静的なものには「いいえ」です。

次に、パフォーマンス。スプリングの使用は非常に遅いという点で正しいですが、起動時にすべてのインジェクションを実行すると、それは1回だけ発生します。Springは、データを渡すシングルトンクラスが多数存在する可能性が高いサーバー側アプリケーションを対象としています。したがって、DBからデータを取得するクラス、処理するクラス、表示するクラスがあり、Springを使用してそれらを相互に接続します。

コマンドラインアプリのように、繰り返し起動するアプリケーションでSpringを使用している場合は、間違った種類のアプリケーションにSpringを使用しているため、ビルダーなどを使用することをお勧めします。Springは、頻繁に再起動されない大規模なエンタープライズアプリを対象としています。

最後に、起動時にクラスのすべての依存関係を単純に挿入し、すべてのクラスでこれを行う場合は、getBeanの処理をまったく行う必要はありません。また、 Beanでinit-methodanddestroy-method属性を使用すると、Springが依存関係の注入を終了した後、プロセスを開始できます。コンテキストをロードするだけで、アプリが起動します(しゃれが意図されています)。

Webプロジェクトの場合、Spring MVCは基本的に制御パターンの反転全体を取得し、それをWebアプリケーションに適用します。春のものはコンテナによってロードされ、Bean名だけを使用して応答するURLを定義できます。そして、ほとんどのコードはpojoのままにすることができます。非常に複雑なものがある場合は、春のWebフローを確認することをお勧めしますが、それを試みる前に、春のfooが非常に強力であることを確認することをお勧めします。

于 2013-02-27T15:10:39.773 に答える
1

getBean()実際にonを呼び出さずに最初のインスタンスを取得する例を次に示しますApplicationContext

public class Test{
  // Declare private static variable so that we can access it in main()
  private static Triangle triangle;

  // Use constructor injection to set the triangle
  public Test(Triangle triangle) {
      Test.triangle = triangle;
  }

  public static void main(String[] args) {
      // Specify the context file containing the bean definitions
      // Spring automatically creates instances of all the beans defined
      // in this XML file. This process is performed before you actually make
      // a getBean("beanName") call.
      ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

      // Use instance methods of triangle 
      Test.triangle.draw();
  }
} 

別の方法を使用できます。

In spring.xml(Bean 構成 XML ファイル)

<bean class="com.example.Test" init-method="myMethod">
    <constructor-args ref="triangle"/>
</bean>

メインクラスに進みましょう

public class Test {
  private final Triangle triangle;

  public Test (Triangle triangle) {
     this.triangle = triangle;
  }

  public static void main (String[] args) {
     ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
  }

  // Called by Spring immediately after the Triangle Bean has been created and
  // all the properties for the bean have been set. This method name must match
  // the one specified with destroy-method attribute in spring.xml
  public void myMethod () {
     triangle.draw();
  }
}
于 2014-08-11T15:57:25.263 に答える