春はどのようなデザインパターンについて話を使用されていますか?
JDKデザインパターンで使用されているもの?春には、これらのデザインパターンで使用される?インタビューの中で、より一般的なこれらの2つの問題を、。私はほとんどステレオタイプ化されている春のためのデザインパターンを説明するための瞬間をインターネットで検索し、ほとんどが昔からあります。だから、それは自分自身に数日かかったあなたはすべてのエラーを指摘することができれば私の個人的な能力、紙を制限するもの総括。また、記事の長さは、私はちょうどに言及したデザインパターンとソースコードのいくつかの解釈のために、この記事の主な目的は、共通のデザインパターンの春を見直すことで、限られています。
デザインパターン(デザインモード)は、オブジェクト指向ソフトウェア開発のベストプラクティスのコンピュータプログラミングです。春のフレームワークは、デザインパターンの異なる種類を多用し、のは最終的にどのようなデザインパターンを見てみましょうか?
制御の反転(IOC)と依存性注入(DI)
IoC(制御の反転、制御フリップは)非常に、非常に重要な概念では春ですが、それは技術が、切り離された設計ではありません。その主な目的は、それによってコードとの間の結合を低減する、(あなただけ使用することができ、オブジェクトを管理しやすいIOC)「第三者」(春即ちIOCコンテナ)によって依存関係を有するオブジェクト間のデカップリングを達成することです程度。IOCは、代わりにパターンを、次のモードの原理である(これらに限定されない)のIoC原理を実現します。
IOC-パターン
春IOCコンテナ、我々はオブジェクトを作成する必要がある場合、あなただけの設定ファイル/注釈が可能に設定することができ、工場のような物体が外に作成されている方法を検討する必要はありません。IOCコンテナは、一緒にオブジェクトを接続するこれらのオブジェクトを設定し、それらが完全に破壊されるまで、これらのオブジェクトの作成からライフサイクル全体を処理するために、オブジェクトを作成する責任があります。
その底部として、数百またはクラスの何千もがある場合は、サービスクラスは、我々はサービスをインスタンス化する必要があり、実際のプロジェクトでは、たびに入れることができます。このサービスのすべての基本となるクラスのコンストラクタを知りたいこと狂った人。IOCの使用した場合、あなただけの設定を行う必要があり、かつ、必要に応じて大幅にプロジェクトの保守性を向上させ、開発の労力を軽減行に引用されました。春IOCの理解については、私はこの答えを見ては、ほとんど知られているお勧めします。
、非常に良いです。
?コントロールは、それを理解するためにどのようにフリップ「、依存オブジェクトのオブジェクトBをオブジェクトがオブジェクトbを使用する必要があるときに自分で作成しなければならないが、オブジェクトAとオブジェクトBが失わ前に、システムは、IOCコンテナを導入した場合:例を与えます。直接リンク。この時間は、オブジェクトがオブジェクトBを使用する必要があるとき、私たちは、ある対象に注入されたオブジェクトBを作成するために、IOCのコンテナを指定することができます。」積極的な行動によるBターゲット依存オブジェクトを取得するプロセスは、名前の反転の起源を制御することである受動的行動、制御反転となります。
DI(依存性注入する、依存性注入)は、コントロールがデザインパターンを達成するために反転され、依存性注入は、オブジェクトに渡されるインスタンス変数です。
工場のデザインパターン
春は工場出荷時のパターンを使用することができるBeanFactory
か、ApplicationContext
Beanオブジェクトを作成します。
2間の比較:
BeanFactory
:遅延注入に比べて、(豆を使用して注入されます)BeanFactory
のプログラムが速く起動、少ないメモリを取る予定です。ApplicationContext
:コンテナの起動、あなたは無用に使用するかどうか、使い捨てのすべてのBeanを作成します。BeanFactory
唯一の最も基本的な依存性注入のサポートを提供し、ApplicationContext
拡大しBeanFactory
、に加えてBeanFactory
、追加の機能は、より多くの機能が含まれ以外の、それは開発者が一般的であるApplicationContext
よりになります。
三つのカテゴリーのApplicationContextの実現:
ClassPathXmlApplication
:コンテキスト・クラスパスリソースとして文書化します。FileSystemXmlApplication
:ファイルシステムのXMLファイルのコンテキスト定義情報が格納されます。XmlWebApplicationContext
:XMLファイル内のWebシステムからの読み込みコンテキスト定義情報。
例:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml");
HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext");
obj.getMsg();
}
}
シングルトンデザインパターン
我々のシステムでは、一部のオブジェクトが実際に存在し、我々は唯一例えば、いずれかが必要:スレッドプール、キャッシュ、ダイアログ、レジストリは、オブジェクトを記録し、オブジェクトは、その上のグラフィックと、お使いのプリンタ用デバイスドライバとして機能します。異常なプログラムの動作、およびリソースの過多量、または結果の矛盾:実際には、オブジェクトのこのタイプは、あなたがそれの複数のインスタンスを作成する場合、いくつかのような問題につながる可能性があり、1つのインスタンスを持つことができます。
Singletonパターンを使用する利点:
- 頻繁に使用されるオブジェクトの場合、あなたができることは、オブジェクトにかかる時間を省略作成、それらのヘビー級のオブジェクトのために、システムのオーバーヘッドの非常に立派な量であり、;
- 新たな操作の数が減少し、したがってに、システムメモリの使用頻度減少する GC休止時間が短く、圧力GCを緩和するであろう。
春豆のデフォルトの範囲はシングルトン(単一の一例)であり、シングルトンスコープに加えて、スプリングスコープ内のBeanの次のタイプがあります。
- プロトタイプ:新しいBeanインスタンスを作成するためのすべての要求。
- リクエスト:各HTTPリクエストは、現在のHTTPリクエストでのみ有効である新しいbeanを生成します。
- セッション:各HTTP要求は、現在のHTTPセッションでのみ有効である新しいbeanを生成します。
- グローバル・セッション:グローバルセッションスコープ、唯一のポートレットWebベースのアプリケーションは、Spring5がなくなって、理にかなっています。小型のJava Webプラグイン断片:ポートレットは、セマンティックコード(HTMLなど)を生成することができます。これらは、ポートレットコンテナのようなHTTPサーブレットの要求として処理することができる基づいています。しかし、別のサーブレットは、それぞれが異なるポートレット・セッションを持っています
単一スプリングの実装例:
- XML:
<bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
- 注意:
@Scope(value = "singleton")
スプリングConcurrentHashMap
シングルモードの具体的な実施形態の方法シングルトンレジストリ。例えば春シングルコアコードは次の通りであります:
// 通过 ConcurrentHashMap(线程安全) 实现单例注册表
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
// 检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//...省略了很多代码
try {
singletonObject = singletonFactory.getObject();
}
//...省略了很多代码
// 如果实例对象在不存在,我们注册到单例注册表中。
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
//将对象添加到单例注册表
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
}
}
}
プロキシデザインパターン
AOP(アスペクト指向プログラミング:指向プログラミング)にかかわらず、サービスのものとすることができるが、論理的または負債サービスモジュール(例えば、トランザクション処理とは、管理、アクセス制御、等ログ)共同コードの重複低減システムを容易にするためにパッケージ化と呼ばれます、モジュール間の結合を低減し、将来の拡張性と保守を容易にします。
春AOPがプロキシオブジェクトがインタフェースを実装している場合、その後、春AOPは、JDKプロキシを使用するプロキシオブジェクトを作成するには、そのオブジェクトがインタフェースを実装していない、動的プロキシに基づいており、春AOPはCGLIBを使用しますが、今回の春AOP以下に示すように、我々は、プロキシエージェントとして、オブジェクトのサブクラスを生成CGLIBを使用します。
もちろん、あなたもAspectJの、春AOPとAspectJの統合を使用することができ、AspectJのJavaはAOPフレームワークの中で最も完全なエコシステムとみなされるべきです。
AOPを使用した後、我々は抽象化、いくつかの共通の特徴を置くことができ、使用が直接大幅に符号量を簡素化され、必要な場合に使用することができます。我々はまた、システムのスケーラビリティを向上する新しい機能を追加する必要がある場合にも便利です。ロギング、トランザクション管理、およびので、現場にはAOPを使用しています。
春AOPとAspectJのAOPの違いは何ですか?
強化された春AOPを実行し、AspectJのは強化され、コンパイルされ属します。スプリングAOP ベースのエージェント(プロキシで)のAspectJに基づいて、バイトコード操作(バイトコード操作)。
春AOPはAspectJのと統合された、AspectJのは、Javaエコシステム上でカウントされなければならないAOPフレームワークの中で最も完全です。より強力に比べて春AOP AspectJのが、春AOP比較的単純で、より弱いです。
我々は、表面をカットした場合は両者の間の比較的小さいので、小さなパフォーマンスの違いです。あまりにも切断した場合しかし、AspectJのための最良の選択は、それが春AOPよりもはるかに高速です。
テンプレートメソッド
テンプレートメソッドデザインパターンは、アルゴリズムの動作のスケルトンを定義する行動パターンであり、サブクラスのいくつかのステップを遅らせます。テンプレートメソッドサブクラスは、アルゴリズムの実装の特定のステップを再定義するアルゴリズムの構造を変更しないことがあります。
public abstract class Template {
//这是我们的模板方法
public final void TemplateMethod(){
PrimitiveOperation1();
PrimitiveOperation2();
PrimitiveOperation3();
}
protected void PrimitiveOperation1(){
//当前类实现
}
//被子类实现的方法
protected abstract void PrimitiveOperation2();
protected abstract void PrimitiveOperation3();
}
public class TemplateImpl extends Template {
@Override
public void PrimitiveOperation2() {
//当前类实现
}
@Override
public void PrimitiveOperation3() {
//当前类实现
}
}
春ではjdbcTemplate
、hibernateTemplate
等クラステンプレートデータベース操作の終わりに、彼らは、テンプレートをモデル化するために使用されます。通常の状況下で、我々は道のテンプレートの継承パターンを使用して達成されますが、春には、このメソッドを使用しますが、しないでテンプレートメソッドパターンコールバックモードを使用して、唯一のコードの再利用の効果を達成するために、だけでなく、柔軟性が向上します。
Observerパターン
オブザーバーパターンは、オブジェクトの行動パターンです。これは、オブジェクトと、オブジェクトが変更された場合、従属オブジェクトのオブジェクトが応答する間の依存関係を有するオブジェクトの種類を示しています。春のイベント駆動型モデルは、古典的なアプリケーションのObserverパターンです。春のイベント駆動型モデルは、我々のコードを分離することができ、多くのシナリオにおいて非常に有用です。例えば、それらは再更新コモディティ指数に必要とされるとき、私たちは商品を追加するたびに、この時間は、我々はこの問題を解決するためにオブザーバーパターンを使用することができます。
オブザーバーパターンは、オブジェクトの行動パターンです。これは、オブジェクトと、オブジェクトが変更された場合、従属オブジェクトのオブジェクトが応答する間の依存関係を有するオブジェクトの種類を示しています。春のイベント駆動型モデルは、古典的なアプリケーションのObserverパターンです。春のイベント駆動型モデルは、我々のコードを分離することができ、多くのシナリオにおいて非常に有用です。例えば、それらは再更新コモディティ指数に必要とされるとき、私たちは商品を追加するたびに、この時間は、我々はこの問題を解決するためにオブザーバーパターンを使用することができます。
3つの役割の春のイベント駆動型モデル
イベントの役割
ApplicationEvent
(org.springframework.context
イベントとして機能するようにパッケージの下の役割が)、これは継承する抽象クラスであるjava.util.EventObject
と実装java.io.Serializable
のインターフェイスを。
春は、デフォルトで以下の事象の存在下で、彼らがしているApplicationContextEvent
(から継承達成しますApplicationContextEvent
):
ContextStartedEvent
:ApplicationContext
イベント起動開始後、ContextStoppedEvent
:ApplicationContext
停止をトリガした後、イベント。ContextRefreshedEvent
:ApplicationContext
初期化またはトリガが完了した後にイベントを更新。ContextClosedEvent
:ApplicationContext
イベント・トリガ閉じた後。
イベントリスナーの役割
ApplicationListener
イベントリスナの役割として作用し、それは単一の定義のインターフェースであるonApplicationEvent()
に対処する方法をApplicationEvent
。ApplicationListener
限り、インターフェイスが実現見られるようなイベントのインタフェース定義に見られるように、ソース・インタフェース・クラスApplicationEvent
、それを。だから、限り、我々は春に達成としてApplicationListener
のインターフェースonApplicationEvent()
リスニングイベントを完了するために、方法
package org.springframework.context;
import java.util.EventListener;
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
イベント出版社の役割
ApplicationEventPublisher
イベントの発行者を務め、それはまた、インターフェースです。
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
ApplicationEventPublisher
インターフェースpublishEvent()
このメソッドはAbstractApplicationContext
、クラスで実装されているあなたはそれが本当にして、イベントであることがわかります、このメソッドを実装して読んApplicationEventMulticaster
放送から出てきます。背後に、ここでは分析されませんあまりにも多くの具体的な内容は、言及した別の記事を書くかもしれません。
イベントの概要の春の流れ
- 実現はから継承:イベントを定義
ApplicationEvent
し、対応するコンストラクタを書きます。 - イベントリスナーを定義します:実装
ApplicationListener
、インタフェースを書き換えるonApplicationEvent()
方法を。 - イベントパブリッシャを使用して発表しました:でニュースを公開する方法。
ApplicationEventPublisher
publishEvent()
例:
// 定义一个事件,继承自ApplicationEvent并且写相应的构造函数
public class DemoEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private String message;
public DemoEvent(Object source,String message){
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
// 定义一个事件监听者,实现ApplicationListener接口,重写 onApplicationEvent() 方法;
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
//使用onApplicationEvent接收消息
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMessage();
System.out.println("接收到的信息是:"+msg);
}
}
// 发布事件,可以通过ApplicationEventPublisher 的 publishEvent() 方法发布消息。
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(String message){
//发布事件
applicationContext.publishEvent(new DemoEvent(this, message));
}
}
お問い合わせの際際の方法を、例えば、コンソールがプリントアウトされます。DemoPublisher
publish()
demoPublisher.publish("你好")
接收到的信息是:你好
アダプタモード
クライアントへの別のインターフェイスへの所望の変換インタフェースにアダプタモード(アダプタパターン)、クラス・インターフェース・アダプタモードは、エイリアスラッパー(ラッパー)仕事、と互換性があってもよいようにします。
アダプタモードスプリングAOP
私たちは、春AOPがプロキシモードに基づいて達成することを知っているが、アダプタモードを使用するには、春AOPの強化や通知(助言)、関連するインタフェースがありますAdvisorAdapter
。アドバイスの一般的なタイプは、次のとおりです。BeforeAdvice
、(ターゲット・メソッド呼び出し、事前通知前) AfterAdvice
(後のアドバイス後の目標メソッド呼び出し、)、 AfterReturningAdvice
(後のように、リターンの前にターゲットメソッドの実行、)。アドバイス(通知)の各タイプは、対応するブロッカーを有します:MethodBeforeAdviceInterceptor
、AfterReturningAdviceAdapter
、AfterReturningAdviceInterceptor
。適応対応するアダプタを介してスプリング事前定義された通知、MethodInterceptor
オブジェクトインタフェース(メソッドインターセプター)のタイプ(例:MethodBeforeAdviceInterceptor
適応担当MethodBeforeAdvice
)。
アダプタモードで春MVC
春MVCにおいて、DispatcherServlet
要求情報を呼び出すことによるHandlerMapping
解像度要求に対応しますHandler
。対応する解決Handler
(つまり、我々は通常言うController
から始まる、コントローラ後)HandlerAdapter
プロセスアダプタ。HandlerAdapter
ターゲットクラスを適応させるための所望のインタフェースの実装クラスの特定のアダプタとして、Controller
クラスアダプタが必要。
なぜアダプタモードでのSpring MVCを使用できますか?スプリングMVCはController
多くの種類の種類のController
要求による処理のための異なる方法。そうでない場合には、アダプタモードの使用DispatcherServlet
対応するタイプへの直接アクセスがController
、それは、同じコードは次のように自己決意する必要があります。
if(mappedHandler.getHandler() instanceof MultiActionController){
((MultiActionController)mappedHandler.getHandler()).xxx
}else if(mappedHandler.getHandler() instanceof XXX){
...
}else if(...){
...
}
我々は追加した場合は1つの以上Controller
の文の種類は、次に上記のコードの行の裁判官を追加することになり、このフォームは維持するプログラムを困難にするだけでなく、開口部の原則に違反し、デザインモード閉じます-拡張子にオープンするが、修正のため閉鎖しました。
Decoratorパターン
オブジェクトへのDecoratorパターンを動的にいくつかの追加の属性や振る舞いを追加することができます。継承の使用と比較して、Decoratorパターンは、より柔軟です。シンプルな少し発言は、私たちが本来の機能を変更する必要がある場合ということですが、私たちは、元のコードを変更するために直接行きたくない、デコレータ外のコードのオリジナルデザインがで設定します。実際には、JDKの多くの場所があるような、Decoratorパターンを使用してInputStream
、家族InputStream
低いクラスたFileInputStream
(原稿の読み取り)、BufferedInputStream
変更せずに(大幅にファイルの読み出し速度を向上させる、キャッシュを増やす)と他のサブクラスをInputStream
拡張コードケースその機能。
Spring構成時にデータソース、データソースは、異なるデータベースおよびデータソースかもしれません。当社は、顧客の需要に応じて動的に元のクラスコードの小さな修正でさまざまなデータソースを切り替えることができますか?今回は(私はまだかなり具体的な原理を理解していない)Decoratorパターンを使用する必要があります。春のモードは、クラス名を含む包装に使用Wrapper
、またはDecorator
。これらのクラスは、基本的に動的オブジェクトに追加の責任を追加しています
概要
これはSpringフレームワークのデザインパターンで使用されます。
- 工場のデザインパターン:工場出荷時のパターンを使用して、春は
BeanFactory
、ApplicationContext
Beanオブジェクトを作成します。 - プロキシデザインパターン:春AOP機能を実装。
- シングルトンデザインパターン:春豆では、デフォルトの単一例です。
- テンプレート方法:春には
jdbcTemplate
、hibernateTemplate
クラステンプレートのデータベース操作の最後に等は、それらがテンプレートをモデル化するために使用されています。 - パッケージデザインパターン:私たちのプロジェクトで複数のデータベースを接続する必要があり、別の顧客は、それぞれ必要に応じて異なるデータベースにアクセスするために訪問します。このモデルは、私たちは、動的に顧客の需要に応じて異なるデータソースを切り替えることができます。
- Observerパターン:春のイベント駆動型モデルは、古典的なアプリケーションのObserverパターンです。
- アダプタモード:春AOPの強化またはアダプタモードを使用するように通知(アドバイス)、スプリングMVCはまた、アダプタモード適応に使用されます
Controller
。 - ......