SpringIocの制御の反転やその他のコンテンツを理解する-初心者のエントリ

いつか

記事の内容の一部は、から来ている
https://gitee.com/zhongfucheng/Java3y#spring%E5%AE%B6%E6%97%8F
http://c.biancheng.net/view/4241.html

背景に注意

Springを学び、ファミリーバケットで遊んでいたとき、IOCやAOP、制御の反転、依存性注入、さらに単純なアノテーションの使用、Beanアセンブリなど、Springの基本的な知識について少し漠然としていたので、インターネット上でさまざまな記事を書いた。、オンライン記事のいくつかは抽象的で、いくつかの例は明るいが圧倒的であるため、私が学んだことを整理するために記事を書く必要があります。

依存性注入

研究例

com.mengma.iocパッケージの下に、PersonDao、PersonDaoImpl、PersonService、PersonServiceImpl、FirstTestの2つのインターフェイス、2つの実装クラス、1つのテストクラス、および5つのファイルを作成します。

package com.mengma.ioc;
public interface PersonDao {
    
    
    public void add();
}


package com.mengma.ioc;
public class PersonDaoImpl implements PersonDao {
    
    
    @Override
    public void add() {
    
    
        System.out.println("save()执行了...");
    }
}



package com.mengma.ioc;
public interface PersonService {
    
    
    public void addPerson();
}



package com.mengma.ioc;
public class PersonServiceImpl implements PersonService {
    
    
    // 定义接口声明
    private PersonDao personDao;
    // 提供set()方法,用于依赖注入
    public void setPersonDao(PersonDao personDao) {
    
    
        this.personDao = personDao;
    }
    // 实现PersonService接口的方法
    @Override
    public void addPerson() {
    
    
        personDao.add(); // 调用PersonDao中的add()方法
        System.out.println("addPerson()执行了...");
    }
}



@Test
public void test1() {
    
    
    // 定义Spring配置文件的路径
    String xmlPath = "applicationContext.xml";
    // 初始化Spring容器,加载配置文件
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            xmlPath);
    // 通过容器获取personService实例
    PersonService personService = (PersonService) applicationContext
            .getBean("personService");
    // 调用personService的addPerson()方法
    personService.addPerson();
}

テストクラスで指定されているため、applicationContext.xmlファイルもiocフォルダーの下に作成されます。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 由 Spring容器创建该类的实例对象 -->
    <bean id="personDao" class="com.mengma.ioc.PersonDaoImpl" />
    <bean id="personService" class="com.mengma.ioc.PersonServiceImpl">
        <!-- 将personDao实例注入personService实例中 -->
        <property name="personDao" ref="personDao"/>
    </bean>
</beans>

プログラムを実行するには、次のパッケージも必要です。
ここに画像の説明を挿入
パッケージのダウンロードアドレス1:https://repo.spring.io/simple/libs-release-local/org/springframework/spring/3.2.2.RELEASE/

パッケージのダウンロードアドレス2:http://commons.apache.org/proper/commons-logging/download_logging.cgi

プログラムの実行結果
ここに画像の説明を挿入
上記のコードでは、最初にpersonDaoオブジェクトが宣言され、依存性注入のためにsetterメソッドが追加され、次にPersonDaoインターフェイスのaddPerson()メソッドが実装され、save()メソッドが呼び出されてメソッドにステートメントが出力されます

applicationContext.xml構成ファイルに要素を追加して、PersonServiceImplクラスをインスタンス化し、personDaoのインスタンスをpersonServiceに挿入します。

出力結果から、Springコンテナを使用してuserServiceのインスタンスを取得した後、インスタンスのaddPerson()メソッドが呼び出され、PersonDao実装クラスのadd()メソッドがこのメソッドで呼び出されることがわかります。結果が出力されます。これはSpringコンテナプロパティセッターインジェクションの方法であり、実際の開発で一般的に使用されている依存性注入方法でもあります。

なぜあなたはこれをしたいのですか?applicationContextを使用する理由、Beanを使用する理由、および依存性注入が必要な理由 コンセプトは何ですか?

抽象化

依存性注入(DI)と制御の反転(Ioc)は同じ意味を持ち、2つの観点から説明された同じ概念です。

Javaインスタンスに別のJavaインスタンスが必要な場合、従来の方法では、呼び出し元が呼び出し先のインスタンスを作成し(たとえば、newキーワードを使用して呼び出し先インスタンスを取得)、Springフレームワークを使用した後、呼び出し先のインスタンスは作成されなくなります。呼び出し元によって作成されますが、Springコンテナーによって作成され、これは制御の反転と呼ばれます。

Springコンテナが呼び出し先のインスタンスを作成すると、呼び出し元が必要とするオブジェクトインスタンスが呼び出し元に自動的に注入されます。このようにして、呼び出し元はSpringコンテナを介して呼び出し先インスタンスを取得します。これは依存性注入と呼ばれます。

依存性注入は制御の反転を実現するための特定の実装方法であるため、簡単に理解できます。

Spring IOCは、オブジェクト管理とオブジェクト依存性の問題を解決します
-3つの曲がりくねった

元々、オブジェクトはすべて新しいものですが、Springを使用する場合は、管理のためにオブジェクトを「IOCコンテナー」に渡します。

「制御の反転」とは、元々「自分で」新しくなったオブジェクトがIOCコンテナに引き渡されることを指します。このオブジェクトの「制御」を「他の当事者」に与えます。「制御の逆転」は、思考または設計パターンのようなものであり、自分の制御下にあるものを「他の人」に任せて処理します。

「依存性注入」とは、「制御の反転」の概念の実現を指します。オブジェクトは、依存関係を作成または管理する必要がなく、依存関係は、それらを必要とするオブジェクトに「自動的に注入」されます。

「依存性注入」と「制御の反転」の最も簡単な理解:元々、オブジェクトはすべて「自分で」新しいものです。次に、このオブジェクトの作成権限とオブジェクト間の依存関係を「IOCコンテナ」に渡します。 。

ここでも問題は、オブジェクトを管理するために「IOCコンテナ」にオブジェクトを渡す必要があるのはなぜですか。

理論的には、「IOCコンテナ」を「ファクトリ」と見なすこともできます。IOCを使用する利点は次のとおりです。

簡単に変更できるオブジェクトの一元管理

結合度を下げます(呼び出し元は自分自身を組み立てる必要も、オブジェクトの実現を気にする必要もありません。「IOCコンテナー」から直接取得するだけです)。

この時点で、2番目の概念であるIocコンテナについて説明する必要があります。

IOCコンテナ

IoCは、プログラム開発において、インスタンスの作成が呼び出し元によって管理されなくなり、Springコンテナーによって作成されることを意味します。Springコンテナは、プログラムコードによって直接制御されるのではなく、プログラム間の関係を制御する役割を果たします。したがって、制御はプログラムコードからSpringコンテナに移され、制御が逆になります。これがSpringのIoCの考え方です。

Springは2つのIoCコンテナー、つまりBeanFactoryとApplicationContextを提供します

「IOCコンテナ」とは何ですか?これは「ファクトリ」として理解でき、オブジェクトの作成やオブジェクト間の依存関係など、すべてのオブジェクトをこの「ファクトリ」に渡して管理します。オブジェクトを使用する必要がある場合は、この「ファクトリ」からオブジェクトを取り出します。

一般的に、SpringのコンテキストであるApplicationContextが一般的に使用されます

つまり、オブジェクトを操作するためにプログラマーを置き換えます。つまり、Beanのライフサイクルを制御します。つまり、プログラマーは「制御の反転」の概念を持ち、「依存性注入」はそれをBeanに与えます。 。これはSpringコンテキストであり、Iocコンテナの一部です。種

上記の例では、
一般に、ApplicationContext.xmlで構成されたBeanオブジェクト:XML構成とアノテーションを使用して多くのBeanをアセンブルし、アノテーションが大部分を占めています。

オブジェクトを「IOCコンテナ」に入れた後、オブジェクトとオブジェクトの間に関係があります。Springにオブジェクト間の依存関係を伝え、オブジェクトの依存関係を解決するのに役立てる必要があります。

「オブジェクト間の関係」についてはあまり考えないでください。実際、日常の開発では、AオブジェクトにBオブジェクトの多くの属性があります。


Springのコアメカニズムとしての依存性注入は、従来のプログラミングの習慣を変えました。コンポーネントのインスタンス化は、アプリケーションによって行われなくなりました。代わりに、必要に応じてアプリケーションに注入されるSpringコンテナによって完了されます。コンポーネント間の依存関係に依存します。デカップリング。これはすべて、Spring構成ファイルで使用されている要素と切り離せません。

春のコンテナは大きな工場と見なすことができ、春のコンテナの豆は工場の製品に相当します。この大きなファクトリでBeanを生成および管理できるようにする場合は、必要なBeanと、これらのBeanを一緒に組み立てる方法をコンテナに指示する必要があります。

ここに画像の説明を挿入

最初のBeanは、id、name、class、scope、refなどのいくつかの重要な属性タグを含むxmlファイルを介して構成されます。必要に応じて、さらに学習を続けることができます。Springの反復により、より多くのアノテーションが追加されました。構成する方法を使用

注釈構成

例を挙げてから、コンセプトについて説明します

研究例

com.mengma.annotationのパッケージの下に、PersonDao、PersonDaoImpl、PersonService、PersonServiceImpl、PersonAction、AnnotationTest、2つの実装クラス、1つの制御クラスと1つのテストクラスの2つのインターフェイスを作成します。6つのファイル

package com.mengma.annotation;
public interface PersonDao {
    
    
    public void add();
}



package com.mengma.annotation;
import org.springframework.stereotype.Repository;
@Repository("personDao")
public class PersonDaoImpl implements PersonDao {
    
    
    @Override
    public void add() {
    
    
        System.out.println("Dao层的add()方法执行了...");
    }
}



package com.mengma.annotation;
public interface PersonService {
    
    
    public void add();
}



package com.mengma.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("personService")
public class PersonServiceImpl implements PersonService {
    
    
    @Resource(name = "personDao")
    private PersonDao personDao;
    public PersonDao getPersonDao() {
    
    
        return personDao;
    }
    @Override
    public void add() {
    
    
        personDao.add();// 调用personDao中的add()方法
        System.out.println("Service层的add()方法执行了...");
    }
}



package com.mengma.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
@Controller("personAction")
public class PersonAction {
    
    
    @Resource(name = "personService")
    private PersonService personService;
    public PersonService getPersonService() {
    
    
        return personService;
    }
    public void add() {
    
    
        personService.add(); // 调用personService中的add()方法
        System.out.println("Action层的add()方法执行了...");
    }
}



package com.mengma.annotation;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationTest {
    
    
    @Test
    public void test() {
    
    
        // 定义Spring配置文件路径
        String xmlPath = "com/mengma/annotation/applicationContext.xml";
        // 初始化Spring容器,加载配置文件,并对bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 获得personAction实例
        PersonAction personAction = (PersonAction) applicationContext
                .getBean("personAction");
        // 调用personAction中的add()方法
        personAction.add();
    }
}

また、構成により、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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
    <context:component-scan base-package="com.mengma.annotation"/>
</beans>

上記のコードでは、最初に@Repositoryアノテーションを使用して、PersonDaoImplクラスをSpringのBeanとして識別します。これは、構成ファイルと同等です。

<bean id = "personDao" class =“ com.mengma.annotation.PersonDaoImpl” />

書き込み。次に、add()メソッドに文を出力して、メソッドが正常に呼び出されたかどうかを確認します。

上記のコードでは、最初に@Serviceアノテーションを使用して、PersonServiceImplクラスをSpringのBeanとして識別します。これは、構成ファイルと同等です。

<bean id = "personService" class =“ com.mengma.annotation.PersonServiceImpl” />

書き込み。

次に、@ Resourceアノテーションを使用して、構成ファイルと同等の属性personDao(personDaoのsetPersonDao()メソッドでもマークできます)をマークします。

<property name = "personDao" ref =“ personDao” />

文言。最後に、このクラスのadd()メソッドのpersonDaoでadd()メソッドを呼び出し、文を出力します。

上記のコードでは、最初に@Controllerアノテーションを使用して、PersonActionクラスにアノテーションを付けます。これは、構成ファイルへの書き込みと同等です。

<bean id = "personAction" class =“ com.mengma.annotation.PersonAction” />

次に、@ Resourceアノテーションを使用して、personServiceをマークします。これは、構成ファイルに書き込むのと同じです。

<property name = "personService" ref =“ personService” />。

最後に、personServiceのadd()メソッドがそのadd()メソッドで呼び出され、文が出力されます。

出力結果から、DAOレイヤー、サービスレイヤー、アクションレイヤーのadd()メソッドがすべて正常に出力されていることがわかります。アノテーションを使用してBeanをアセンブルする方法が正常に実装されていることがわかります。

概念

Springでは、XML構成ファイルを使用することでBeanのアセンブリを実現できますが、アプリケーション内のBeanの数が多いと、XML構成ファイルが肥大化しすぎて、保守やアップグレードに一定の問題が発生します。

JavaはJDK5.0以降、アノテーション(アノテーション)機能を提供しており、Springはアノテーションテクノロジーの包括的なサポートも提供しています。Spring3では一連のアノテーションが定義されています。一般的に使用されるアノテーションは次のとおりです。
@Component
は、このアノテーションを使用してSpringのBeanを記述することができますが、これはコンポーネント(Bean)のみを表す一般化された概念であり、任意のレベルで適用できます。使用する場合は、対応するクラスに注釈を付けるだけです。
@Repositoryは
、SpringのBeanとしてデータアクセス層(DAO層)クラスを識別するために使用され、その機能は@Componentと同じです。
@Service
は通常、ビジネス層(サービス層)で機能し、Springでビジネス層クラスをBeanとして識別するために使用され、その機能は@Componentと同じです。
@Controller
は通常、コントロールレイヤー(Struts2 Actionなど)で動作し、SpringでコントロールレイヤークラスをBeanとして識別するために使用され、その機能は@Componentと同じです。
@Autowiredは
、Beanの属性変数、Setメソッド、および属性のコンストラクターに注釈付けるために使用され、対応する注釈プロセッサーと連携してBeanの自動構成を完了します。アセンブリは、デフォルトでBeanのタイプに従って実行されます。
@Resourceは、
Autowiredと同じ効果があります。違いは、@ AutowiredはデフォルトでBeanタイプによってアセンブルされるのに対し、@ ResourceはデフォルトでBeanインスタンス名によってアセンブルされることです。

@Resourceには、名前とタイプという2つの重要な属性があります。

Springは、name属性をBeanインスタンス名に解決し、type属性をBeanインスタンスタイプに解決します。name属性が指定されている場合、アセンブリはインスタンス名に従って実行されます。type属性が指定されている場合、アセンブリはBeanタイプに従って実行されます。

どちらも指定されていない場合は、最初にBeanインスタンス名に従ってアセンブルされ、一致しない場合はBeanタイプに従ってアセンブルされます。一致しない場合は、NoSuchBeanDefinitionExceptionがスローされます。
@Qualifier
アノテーションと@Autowiredアノテーションは一緒に使用され、Beanタイプによるデフォルトのアセンブリは、Beanのインスタンス名によるアセンブリに変更されます。Beanのインスタンス名は、@ Qualifierアノテーションのパラメーターによって指定されます。

おすすめ

転載: blog.csdn.net/weixin_43596589/article/details/112949217