web-dev-qa-db-ja.com

自動配線はSpringでどのように機能しますか?

コントロールの反転IoC)がSpringでどのように機能するかについては少し混乱しています。

UserServiceImplインターフェースを実装するUserServiceというサービスクラスがあるとします。

これはどのように@Autowiredになりますか?

そして私のControllersでは、どのようにしてinstantiateをこのサービスのinstanceにすることができますか?

次のようにしますか。

UserService userService = new UserServiceImpl();
453
Blankman

まず、そして最も重要なこと - すべてのSpring Beanは管理されています - それらは「アプリケーションコンテキスト」と呼ばれるコンテナの中に「住んでいます」。

次に、各アプリケーションはそのコンテキストへのエントリポイントを持ちます。 Webアプリケーションにはサーブレットがあります。 _ jsf _ はel-resolverなどを使用します。また、アプリケーションコンテキストがブートストラップされ、すべてのBeanが自動生成される場所もあります。 Webアプリケーションでは、これは起動リスナーになる可能性があります。

自動配線は、あるBeanのインスタンスを別のBeanのインスタンスの目的のフィールドに配置することによって行われます。両方のクラスはBeanであるべきです、すなわち、それらはアプリケーションコンテキストの中で生きるように定義されるべきです。

アプリケーションのコンテキストで「生きる」とは何ですか?これは context があなたではなくオブジェクトをインスタンス化することを意味します。すなわち - あなたは決してnew UserServiceImpl()を作ることはありません - コンテナは各インジェクションポイントを見つけてそこにインスタンスを設定します。

あなたのコントローラでは、あなただけのものがあります:

@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {

    // Tells the application context to inject an instance of UserService here
    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    public void login(@RequestParam("username") String username,
           @RequestParam("password") String password) {

        // The UserServiceImpl is already injected and you can use it
        userService.login(username, password);

    }
}

いくつかのメモ:

  • applicationContext.xmlでは、クラスが<context:component-scan>@Controllerなどのアノテーションについてスキャンされるように@Serviceを有効にする必要があります。
  • Spring-MVCアプリケーションのエントリポイントはDispatcherServletですが、それはあなたからは見えません。そのため、アプリケーションコンテキストの直接の対話とブートストラップは舞台裏で行われます。
  • UserServiceImplもbeanとして定義する必要があります - <bean id=".." class="..">を使用するか@Serviceアノテーションを使用するかのいずれかです。これがUserServiceの唯一の実装者になるので、注入されます。
  • @Autowiredアノテーションとは別に、SpringはXML設定可能な自動配線を使うことができます。その場合、既存のBeanと一致する名前またはタイプを持つすべてのフィールドに、自動的にBeanが注入されます。実際、これは自動配線の最初のアイデアでした。設定を行わずにフィールドに依存関係を注入することでした。 @Inject@Resourceのような他の注釈も使用することができます。
644
Bozho

注釈ルートとBean XML定義ルートのどちらを使用したかによって異なります。

applicationContext.xmlにBeanが定義されているとします。

<beans ...>

    <bean id="userService" class="com.foo.UserServiceImpl"/>

    <bean id="fooController" class="com.foo.FooController"/>

</beans>

自動配線はアプリケーションの起動時に行われます。そのため、引数としてfooControllerクラスを使いたいUserServiceImplでは、次のように注釈を付けます。

public class FooController {

    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

@Autowiredが見つかると、SpringはapplicationContext内のプロパティと一致するクラスを探し、それを自動的に挿入します。複数のUserService Beanがある場合は、どちらを使用するかを修飾する必要があります。

次のようにします。

UserService service = new UserServiceImpl();

自分で設定しない限り、@ Autowiredは拾われません。

61
Ben J

@AutowiredはSpring 2.5で導入されたアノテーションで、インジェクションのためだけに使われています。

例えば:

class A {

    private int id;

    // With setter and getter method
}

class B {

    private String name;

    @Autowired // Here we are injecting instance of Class A into class B so that you can use 'a' for accessing A's instance variables and methods.
    A a;

    // With setter and getter method

    public void showDetail() {
        System.out.println("Value of id form A class" + a.getId(););
    }
}
18
mohit bansal

@Autowiredは内部的にどのように機能しますか?

元 -

class EnglishGreeting {
   private Greeting greeting;
   //setter and getter
}

class Greeting {
   private String message;
   //setter and getter
}

@Autowiredを使用していない場合は、.xmlファイルに似ている

<bean id="englishGreeting" class="com.bean.EnglishGreeting">
   <property name="greeting" ref="greeting"/>
</bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

@Autowiredを使用している場合

class EnglishGreeting {
   @Autowired //so automatically based on the name it will identify the bean and inject.
   private Greeting greeting;
   //setter and getter
}

@Autowiredを使用していない場合は、.xmlファイルに似ている

<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

それでも疑問がある場合は、次にライブデモの下に進んでください。

@Autowiredはどのように内部的に機能しますか?

9

サービスクラスUserServiceImplにアノテーションを付ける必要があるだけです。

@Service("userService")

Springコンテナーは、サービスとして登録されるときにこのクラスのライフサイクルの面倒を見ます。

それからあなたのコントローラで、あなたはそれを自動配線(インスタンス化)してその機能を使うことができます。

@Autowired
UserService userService;
4
Jitender Chahar

Springの依存関係を注入すると、クラスからカップリングを取り除くのに役立ちます。このようなオブジェクトを作成する代わりに

UserService userService = new UserServiceImpl();

あなたはDIを導入した後これを使うでしょう

@Autowired
private UserService userService;

これを実現するには、ServiceConfigurationファイルにサービスのBeanを作成する必要があります。その後、そのServiceConfigurationクラスをWebApplicationConfigurationクラスにインポートして、このようにそのBeanをコントローラに自動配線できるようにする必要があります。

public class AccController {

    @Autowired
    private UserService userService;
} 

Java構成ベースのPOCはここにあります example

1
AbdusSalam

@Autowiredを使用してインスタンスを作成する方法は3つあります。

1。@Autowired on Properties

アノテーションはプロパティで直接使用できるため、ゲッターとセッターの必要がなくなります。

    @Component("userService")
    public class UserService {

        public String getName() {
            return "service name";
        }
    }

    @Component
    public class UserController {

        @Autowired
        UserService userService

    }

上記の例では、SpringはuserServiceが作成されたときにUserControllerを探して挿入します。

2。セッターの@Autowired

@Autowired注釈は、セッターメソッドで使用できます。次の例では、アノテーションがセッターメソッドで使用されると、userServiceが作成されたときに、UserControllerのインスタンスを使用してセッターメソッドが呼び出されます。

public class UserController {

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
            this.userService = userService;
    }
}

@Autowired on Constructors

@Autowired注釈は、コンストラクターでも使用できます。以下の例では、注釈がコンストラクターで使用される場合、userServiceのインスタンスが、UserControllerが作成されるときにコンストラクターへの引数として挿入されます。

public class UserController {

    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService= userService;
    }
}
0
Mak

制御の逆転という全体的な概念は、手動でオブジェクトをインスタンス化し、必要なすべての依存関係を提供するという面倒な作業から解放されることを意味します。あなたが適切なアノテーション(例えば@Service)でクラスにアノテーションを付けると、Springは自動的にオブジェクトをインスタンス化します。注釈に慣れていない場合は、代わりにXMLファイルを使用することもできます。ただし、スプリングコンテキスト全体をロードしたくない場合は、ユニットテストでクラスを手動で(newキーワードを使用して)インスタンス化することはお勧めできません。

0
k13i

Springの設定ファイルに<context:annotation-config/>要素を追加して@Autowiredアノテーションを有効にする必要があることに注意してください。これは、注釈の処理を引き受けるAutowiredAnnotationBeanPostProcessorを登録します。

そして、Field Injectionメソッドを使ってサービスを自動配線することができます。

public class YourController{

 @Autowired
 private UserService userService; 

}

これをポストから見つけました Spring @autowiredアノテーション

0
David Pham