コントロールの反転 (IoC
)がSpring
でどのように機能するかについては少し混乱しています。
UserServiceImpl
インターフェースを実装するUserService
というサービスクラスがあるとします。
これはどのように@Autowired
になりますか?
そして私のControllers
では、どのようにしてinstantiate
をこのサービスのinstance
にすることができますか?
次のようにしますか。
UserService userService = new UserServiceImpl();
まず、そして最も重要なこと - すべての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
を有効にする必要があります。UserServiceImpl
もbeanとして定義する必要があります - <bean id=".." class="..">
を使用するか@Service
アノテーションを使用するかのいずれかです。これがUserService
の唯一の実装者になるので、注入されます。@Autowired
アノテーションとは別に、SpringはXML設定可能な自動配線を使うことができます。その場合、既存のBeanと一致する名前またはタイプを持つすべてのフィールドに、自動的にBeanが注入されます。実際、これは自動配線の最初のアイデアでした。設定を行わずにフィールドに依存関係を注入することでした。 @Inject
、@Resource
のような他の注釈も使用することができます。注釈ルートと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は拾われません。
@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(););
}
}
@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>
それでも疑問がある場合は、次にライブデモの下に進んでください。
サービスクラスUserServiceImplにアノテーションを付ける必要があるだけです。
@Service("userService")
Springコンテナーは、サービスとして登録されるときにこのクラスのライフサイクルの面倒を見ます。
それからあなたのコントローラで、あなたはそれを自動配線(インスタンス化)してその機能を使うことができます。
@Autowired
UserService userService;
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
@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;
}
}
制御の逆転という全体的な概念は、手動でオブジェクトをインスタンス化し、必要なすべての依存関係を提供するという面倒な作業から解放されることを意味します。あなたが適切なアノテーション(例えば@Service
)でクラスにアノテーションを付けると、Springは自動的にオブジェクトをインスタンス化します。注釈に慣れていない場合は、代わりにXMLファイルを使用することもできます。ただし、スプリングコンテキスト全体をロードしたくない場合は、ユニットテストでクラスを手動で(new
キーワードを使用して)インスタンス化することはお勧めできません。
Springの設定ファイルに<context:annotation-config/>
要素を追加して@Autowiredアノテーションを有効にする必要があることに注意してください。これは、注釈の処理を引き受けるAutowiredAnnotationBeanPostProcessorを登録します。
そして、Field Injectionメソッドを使ってサービスを自動配線することができます。
public class YourController{
@Autowired
private UserService userService;
}
これをポストから見つけました Spring @autowiredアノテーション