スプリングの三角形を理解!
この文章の目的は?
スプリングコア三角形-IoC/DI、AOP、PSAについて説明します.
IoC vs DI
制御反転(IOC)と依存注入(DI)は全体としては異なる意味を持つ.
IoCは開発者ではなくスプリングによってコードストリームを制御する概念である.次のコードは、開発者がコードストリームを直接制御する例です.public class A {
private B b;
public A() {
b = new B();
}
}
逆に、オブジェクトがスプリングコンテナによって管理されている空の場合、@Autowired
操作によってオブジェクトを入力することができる.これは、開発者がスプリングコンテナから直接オブジェクトを作成し、直接オブジェクトを管理するのではなく、オブジェクトに注入することを意味します.public class A {
@Autowired
private B b;
}
したがって,IoCは開発者ではなく,スプリングがコードの流れを逆に制御し,これが制御の逆転である.スプリングによって制御されるため,開発者の負担が小さく,SOLIDの原則を遵守しやすく,柔軟なコード構造を用いて開発することができる.
ではDIとは何でしょうか.IoCはスプリングにのみ使用される概念ではなく、広く使用されている用語であるため、スプリングをIoC容器と定義しても、スプリングが提供する機能を明確に説明することはできない.そこで,より核心的な意味を教えるためにDIの概念を採用した.簡単に言えば、DIはIoCプログラミングモデルを実現する方法の一つである.
IoCとDI-「スプリングの中で、IoCは具体的にDI方式で依存性逆転制御を行います!
依存性注入方法
依存注入法は3種類ある.コンストラクション関数と属性を用いた依存性注入は,単純にコードで見るだけで,XMLを用いた依存性注入の方法をより詳細にまとめる.
制御反転(IOC)と依存注入(DI)は全体としては異なる意味を持つ.
IoCは開発者ではなくスプリングによってコードストリームを制御する概念である.次のコードは、開発者がコードストリームを直接制御する例です.
public class A {
private B b;
public A() {
b = new B();
}
}
逆に、オブジェクトがスプリングコンテナによって管理されている空の場合、@Autowired
操作によってオブジェクトを入力することができる.これは、開発者がスプリングコンテナから直接オブジェクトを作成し、直接オブジェクトを管理するのではなく、オブジェクトに注入することを意味します.public class A {
@Autowired
private B b;
}
したがって,IoCは開発者ではなく,スプリングがコードの流れを逆に制御し,これが制御の逆転である.スプリングによって制御されるため,開発者の負担が小さく,SOLIDの原則を遵守しやすく,柔軟なコード構造を用いて開発することができる.ではDIとは何でしょうか.IoCはスプリングにのみ使用される概念ではなく、広く使用されている用語であるため、スプリングをIoC容器と定義しても、スプリングが提供する機能を明確に説明することはできない.そこで,より核心的な意味を教えるためにDIの概念を採用した.簡単に言えば、DIはIoCプログラミングモデルを実現する方法の一つである.
IoCとDI-「スプリングの中で、IoCは具体的にDI方式で依存性逆転制御を行います!
依存性注入方法
依存注入法は3種類ある.コンストラクション関数と属性を用いた依存性注入は,単純にコードで見るだけで,XMLを用いた依存性注入の方法をより詳細にまとめる.
ジェネレータを使用して依存項目を注入する
public interface Tire {
String getBrand();
}
public class KoreaTire implements Tire {
public String getBrand() {
return "코리아 타이어";
}
}
public class AmericaTire implements Tire {
public String getBrand() {
return "미국 타이어";
}
}
public class Car {
Tire tire;
public Car(Tire tire) {
this.tire = tire;
}
public String getTireBrand() {
return "장착된 타이어: " + tire.getBrand();
}
}
public class Driver {
public static void main(String[] args) {
Tire tire = new KoreaTire();
Car car = new Car(tire);
System.out.println(car.getTireBrand());
}
}
属性注入依存性の使用
生成者の依存性注入を用いてタイヤを装着すると、タイヤを交換することができなくなる.運転手がより現実的にタイヤを交換できるように,属性依存注入を用いることができる.ジェネレータを使用する依存注入コードでは、一部のみ変更されます.
public class Car {
Tire tire;
public Tire getTire() {
return tire;
}
public void setTire(Tire tire) {
this.tire = tire;
}
public String getTireBrand() {
return "장착된 타이어: " + tire.getBrand();
}
}
public class Driver {
public static void main(String[] args) {
Tire tire = new KoreaTire();
Car car = new Car();
car.setTire(tire);
System.out.println(car.getTireBrand());
}
}
💡 属性で依存性を注入するよりも、生成者を使った依存性注入が人気?上のタイヤの例を考えてみましょう.実際、私たちは数十年来、車を運転してタイヤを交換する仕事が普通の運転手であることはめったにありません.つまり,現実に頻繁に変化することがなければ,生成者の依存性を用いて注入する傾向がある.
XML注入依存性の使用
本ではXMLを総合ショッピングモールの役割として描いている.上記の使用ジェネレータおよび属性の依存注入例では、運転手が直接車およびタイヤを作成した場合、XMLの依存注入で運転手がXMLに登録された車およびタイヤを選択する概念を使用する.したがって、XMLを使用すると、再コンパイルや再配置を必要とせず、XMLファイルを変更するだけでプログラムの実行結果を変更できます.
XMLデフォルト注入
<!-- xml 파일 위치 : src/main/java/expert002/expert002.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.xsd">
<bean id="mainTire" class="expert002.KoreaTire"></bean>
<bean id="americaTire" class="expert002.AmericaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
</beans>
public class Driver {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("expert002/expert002.xml");
Car car = context.getBean("car", Car.class);
Tire tire = context.getBean("mainTire", Tire.class);
car.setTire(tire);
System.out.println(car.getTireBrand());
}
}
XML属性の入力
<!-- xml 파일 위치 : src/main/java/expert002/expert002.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.xsd">
<bean id="mainTire" class="expert002.KoreaTire"></bean>
<bean id="americaTire" class="expert002.AmericaTire"></bean>
<bean id="car" class="expert002.Car">
<property name="tire" ref="mainTire"></property>
</bean>
</beans>
public class Driver {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("expert002/expert002.xml");
Car car = context.getBean("car", Car.class);
System.out.println(car.getTireBrand());
}
}
@Autowired注入
@Autowired
Arnovationでは、Springフレームワークがコンフィギュレーション・メソッドを使用することなく、コンフィギュレーション・ファイルに属性を注入できます.<!-- xml 파일 위치 : src/main/java/expert002/expert002.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/spring-context-3.1.xsd">
<context:annotation-config />
<bean id="mainTire" class="expert002.KoreaTire"></bean>
<bean id="americaTire" class="expert002.AmericaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
</beans>
public class Car {
@Autowired
Tire mainTire;
public String getTireBrand() {
return "장착된 타이어: " + mainTire.getBrand();
}
}
プライマリタイヤをアメリカンタイヤに設定する場合は、XMLファイルにアメリカンタイヤに対応するスペースを見つけ、idをMainTireに変更します.<!-- xml 파일 위치 : src/main/java/expert002/expert002.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/spring-context-3.1.xsd">
<context:annotation-config />
<bean id="koreaTire" class="expert002.KoreaTire"></bean>
<bean id="mainTire" class="expert002.AmericaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
</beans>
違う状況を見てみましょう.🤓@Autowired-XMLのid属性は存在しません
下部コードの結果は
@Autowired
で正常に動作します.なぜなら、KoreaTire
クラスはTire
クラスを継承しているからです.@Autowired
Tire tire
<bean class="expert002.KoreaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
@Autowired-XMLのid属性が一致しません
前述したように、
@Autowired
はtype属性よりも優先される.したがって,idが異なっていても正常に動作する.@Autowired
Tire tire
<bean id="differentTireName" class="expert002.KoreaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
@Autowired-XMLにはid属性がなく、同じbeanが2つしかありません。
結果は失敗です.理由は当然です.idプロパティがなく、同じタイプの2つの空がある場合、springはどの空に一致するべきか分からないからです.
@Autowired
Tire tire
<bean class="expert002.KoreaTire"></bean>
<bean class="expert002.AmericaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
@Autowired-XMLの他のタイプですが、idが一致する場合があります。
この場合、異なるtypeですが、idが一致してもtypeのスペースが一致します.
@Autowired
Tire tire
<bean class="expert002.KoreaTire"></bean> <!-- 매칭 -->
<bean id="tire" class="expert002.Door"></bean>
<bean id="car" class="expert002.Car"></bean>
@Resource注入
@Resource
はjava標準言語で、スプリングフレームを使用しなくても使用できます.本の中の筆者は,@Autowired
より@Resource
音声の方が適切であると述べている.車の立場では、タイヤが資源のようにより直感的に表現できるからだ.ただし、構文ごとに空の属性の優先度が異なることに注意してください.
@Autowired
の優先度はtype(class)、後にid@Resource
の優先度はidの次のタイプ(クラス)@Resource
よりXML属性注入(property)を使用したほうがいいですか?本書では
@Resource
の方が開発効率は良いが、XMLファイルだけを見ても簡単にDI関係を特定でき、メンテナンス性に優れ、XMLファイルも用途別に分離できるので、XML属性注入(property)を使う方法をお勧めします.@Qualifier(""), @Resource(name="")
XMLファイルを作成する場合、特定のidを使用してクラスの属性名と一致しないように構成する場合は、name属性
@Autowired
および@Qualifier
を使用します.<bean id="differentTireName" class="expert002.KoreaTire"></bean>
<bean id="car" class="expert002.Car"></bean>
@Autowired
@Qualifier("differentTireName")
Tire tire
@Resource(name = "differentTireName")
Tire tire
AOP
ビュー向けプログラミング(AOP)は,記録,セキュリティ,トランザクションなどが繰り返される横断的な注目点とコア的な注目点を分けて集中的に管理する方法である.AOPによって実現されるコードは、さらなる開発とメンテナンスに有利であり、単一責任原則を適用する.ここでは使い方よりも、特徴だけ整理しておきます.
AOPで覚えておきたいポイントは大体3つ.
@Resource
である.特に、「観察」という言葉を説明すれば、AOPのほうが分かりやすい.AdvisorはSpring AOPでのみ使用される用語です.Asspectに示すように、Advisorは正式に次のように表示されます.
すなわち,AOPがいつ注目点を横切るかを定義するプログラミング技術であると考えると,容易に実現できる.
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<aop:asepctj-autoproxy />
<bean id="myAspect" class="aop002.MyAspect"></bean>
<bean id="boy" class="aop002.Boy"></bean>
<bean id="girl" class="aop002.Girl"></bean>
</beans>
@Aspect
public class MyAspect {
@Pointcut("execution(* runSomething())")
private void iampc() {
// 의미 없는 코드 블록
}
// @Before("execution(* runSomething())")
@Before("iampc()")
public void before(JoinPoint joinPoint) {
System.out.println("AOP 적용 (before)");
}
@After("iampc()")
public void lockDoor(JoinPoint joinPoint) {
System.out.println("AOP 적용 (after)");
}
}
上記のコードが宣言に基づいてAOPを適用した場合、POJOとXMLに基づくAOPは以下のようになる.<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<aop:asepctj-autoproxy />
<bean id="myAspect" class="aop002.MyAspect"></bean>
<bean id="boy" class="aop002.Boy"></bean>
<bean id="girl" class="aop002.Girl"></bean>
<aop:config>
<aop:pointcut expression="execution(* runSomething())" id="iampc" />
<aop:aspect ref="myAspect">
<!--
<aop:before method="before" pointcut="execution(* runSomething())" />
<aop:after method="lockDoor" pointcut="execution(* runSomething())" />
-->
<aop:before method="before" pointcut-ref="iampc" />
<aop:before method="lockDoor" pointcut-ref="iampc" />
</aop:aspect>
</aop:config>
</beans>
public class MyAspect {
public void before(JoinPoint joinPoint) {
System.out.println("AOP 적용 (before)");
}
public void lockDoor(JoinPoint joinPoint) {
System.out.println("AOP 적용 (after)");
}
}
PSA
移植可能サービス抽象(PSA)は、一貫したサービス抽象と呼ばれる.サービス抽象化とは、JDBCのようにアダプタモードを利用して汎用インタフェース制御によって同じ動作を実行できるサービス抽象化の多くの技術である.Springは、様々な技術(オブジェクトXMLマッピング-オブジェクトからXMLマッピング)、ORM、キャッシュ、トランザクションなどにPSAを提供する.
本文の参考
Reference
この問題について(スプリングの三角形を理解!), 我々は、より多くの情報をここで見つけました https://velog.io/@maketheworldwise/스프링의-삼각형-이해하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol