回答:
まず、最も重要なことは、すべてのSpring Beanが管理されていることです。これらは、「アプリケーションコンテキスト」と呼ばれるコンテナ内で「ライブ」です。
次に、各アプリケーションにはそのコンテキストへのエントリポイントがあります。Webアプリケーションにはサーブレットがあり、JSFはel-resolverなどを使用します。また、アプリケーションコンテキストがブートストラップされ、すべてのBeanが自動接続される場所があります。Webアプリケーションでは、これはスタートアップリスナーになります。
自動配線は、あるBeanのインスタンスを別のBeanのインスタンスの目的のフィールドに配置することによって行われます。どちらのクラスもBeanである必要があります。つまり、アプリケーションコンテキストで実行されるように定義する必要があります。
アプリケーションのコンテキストで「生きている」とは何ですか?これは、コンテキストがあなたではなくオブジェクトをインスタンス化することを意味します。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 id=".." class="..">
を使用するか使用して、Beanとしても定義する必要があります@Service
。の唯一の実装者UserService
になるため、挿入されます。@Autowired
アノテーションとは別に、SpringはXMLで構成可能な自動配線を使用できます。その場合、既存のBeanと一致する名前またはタイプを持つすべてのフィールドに、自動的にBeanが挿入されます。実際、これは自動配線の最初のアイデアでした。設定なしでフィールドに依存関係を挿入することです。以下のような他の注釈は@Inject
、@Resource
また、使用することができます。アノテーションルートが必要か、Bean XML定義ルートが必要かによって異なります。
あなたがあなたの中で定義された豆を持っていたとしましょうapplicationContext.xml
:
<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を使用している場合は、使用するBeanを限定する必要があります。
次の場合:
UserService service = new UserServiceImpl();
@Autowired
自分で設定しない限り、はピックアップされません。
bean id
にはapplicationContext.xml
。タイプでuserService
変数を定義する必要がありますUserService
。では、なぜxml
ファイルにエントリを作成するのか。
@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
「B
クラスからクラス内のすべての関数(メソッド)と変数を使用できる」という意味ではありませんA
。何それがないことのインスタンスもたらしているA
のインスタンスにしB
、あなたが行うことができますa.getId()
からB
。
@Autowired
内部ではどのように機能しますか?
例:
class EnglishGreeting {
private Greeting greeting;
//setter and getter
}
class Greeting {
private String message;
//setter and getter
}
.xmlファイルを使用しない場合は、@Autowired
次のようになります。
<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
}
.xmlファイルを使用しない場合は、@Autowired
次のようになります。
<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;
}
標準的な方法:
@RestController
public class Main {
UserService userService;
public Main(){
userService = new UserServiceImpl();
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
ユーザーサービスインターフェイス:
public interface UserService {
String print(String text);
}
UserServiceImplクラス:
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
出力: Example test UserServiceImpl
これは密結合クラスの優れた例であり、設計例が悪いため、テストに問題があります(PowerMockitoも悪い)。
次に、疎結合の良い例であるSpringBoot依存性注入を見てみましょう。
インターフェースは変わりませんが、
メインクラス:
@RestController
public class Main {
UserService userService;
@Autowired
public Main(UserService userService){
this.userService = userService;
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
ServiceUserImplクラス:
@Component
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
出力: Example test UserServiceImpl
そして今、テストを書くのは簡単です:
@RunWith(MockitoJUnitRunner.class)
public class MainTest {
@Mock
UserService userService;
@Test
public void indexTest() {
when(userService.print("Example test")).thenReturn("Example test UserServiceImpl");
String result = new Main(userService).index();
assertEquals(result, "Example test UserServiceImpl");
}
}
私が示した@Autowired
コンストラクタに注釈をそれはまた、セッターまたはフィールド上で使用することができます。
Spring 構成ファイルに@Autowired
要素<context:annotation-config/>
を追加してアノテーションを有効にする必要があることに注意してください。これはAutowiredAnnotationBeanPostProcessor
、アノテーションの処理を処理するを登録します。
そして、フィールドインジェクション方式を使用してサービスを自動配線できます。
public class YourController{
@Autowired
private UserService userService;
}
私はこれをSpring @autowiredアノテーションの投稿から見つけました
を使用してインスタンスを作成する方法は3つあります@Autowired
。
1. @Autowired
プロパティについて
アノテーションはプロパティで直接使用できるため、ゲッターとセッターの必要がなくなります。
@Component("userService")
public class UserService {
public String getName() {
return "service name";
}
}
@Component
public class UserController {
@Autowired
UserService userService
}
上記の例では、Springはが作成されたuserService
ときに検索して注入しUserController
ます。
2. @Autowired
セッターについて
@Autowired
注釈は、setterメソッドで使用することができます。以下の例では、setterメソッドでアノテーションが使用されている場合、setterメソッドはuserService
when UserController
が作成されたときのインスタンスで呼び出されます。
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
3. @Autowired
コンストラクタについて
@Autowired
注釈はまた、コンストラクタで使用することができます。以下の例では、アノテーションがコンストラクターで使用されている場合、のインスタンスが作成userService
時にコンストラクターへの引数として挿入されますUserController
。
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService= userService;
}
}
簡単に言えば、自動配線、つまり自動的にリンクを配線することですが、これを誰がどのような種類の配線で行うかという問題が生じます。答えは次のとおりです。コンテナがこれを行い、セカンダリタイプの配線がサポートされます。プリミティブは手動で実行する必要があります。
質問:コンテナはどのようなタイプの配線をどのようにして知るのですか?
回答:これをbyType、byName、constructorと定義します。
質問:自動配線のタイプを定義しない方法はありますか?
回答:はい、@ Autowiredという1つのアノテーションを実行することで実現します。
質問:しかし、システムはどのようにしてこのタイプの二次データを選択する必要があるのでしょうか
回答:そのデータをspring.xmlファイルで提供するか、クラスにsterotypeアノテーションを使用して、コンテナー自体がオブジェクトを作成できるようにします。