まず、Spring について簡単に紹介します。
Spring は、制御反転 (IoC) とアスペクト指向 (AOP) の 2 つのコアを備えたオープンソースの軽量 Java 開発フレームワークです。 Java Spring フレームワークは、宣言的な方法でトランザクションを柔軟に管理し、開発効率と品質を向上させます。
(推奨チュートリアル: java 入門チュートリアル)
Spring フレームワークはサーバーサイド開発に限定されません。すべての Java アプリケーションは、シンプルさ、テスト容易性、疎結合の点で Spring の恩恵を受けることができます。 Spring フレームワークは強力な接着プラットフォームでもあり、独自の機能を提供するだけでなく、他のテクノロジーやフレームワークを接着する機能も提供します。
次は具体的な内容を詳しく紹介していきます。
Inversion of Control (IOC)
従来、ビジネス ロジック層のコードは次のように記述されることが多かったです。
public class PersonServiceBean { private PersonDao personDao = new PersonDaoBean(); public void save(Person person){ personDao.save(person); } }
上記では、PersonDaoBean がアプリケーション内で作成され、維持されます。いわゆる制御の反転とは、アプリケーション自体は依存オブジェクトの作成と保守を担当せず、外部コンテナーが依存オブジェクトの作成と保守を担当することを意味します。このようにして、アプリケーションから外部コンテナに制御が移ることをリバーサルといいます。
依存関係インジェクション
依存関係オブジェクトを作成のために外部コンテナに渡すと、PersonServiceBean クラスを次のように変更できます。
public class PersonServiceBean { private PersonDao personDao ; // 通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。 public PersonServiceBean(PersonDao personDao){ this.personDao=personDao; } public void save(Person person){ personDao.save(person); } }
いわゆる依存関係インジェクションとは、実行時に、外部コンテナが依存オブジェクトをコンポーネントに動的に挿入することを指します。
なぜ Spring を使用するのでしょうか?
少なくとも私の意見では、Spring をプロジェクトに導入すると、すぐに次のような利点がもたらされます:
コンポーネント間の結合を減らし、ソフトウェアのさまざまなレイヤー間の分離を実現します。
トランザクション管理サービス、メッセージ サービスなど、コンテナによって提供される多くのサービスを使用できます。コンテナを使用してトランザクションを管理すると、開発者はトランザクションを手動で制御する必要がなくなり、複雑なトランザクションの伝播に対処する必要もなくなります。
コンテナーはシングルトン モードのサポートを提供するため、開発者は自分で実装コードを記述する必要がなくなりました。
コンテナは、アクセス許可のインターセプトやランタイム監視などの機能を簡単に実装するために使用できる AOP テクノロジを提供します。
コンテナには多くの補助クラスが用意されており、これらのクラスを使用すると、JdbcTemplate、HibernateTemplate などのアプリケーション開発を高速化できます。
Spring は、Hibernate、JPA、Struts などの統合など、主流のアプリケーション フレームワークの統合サポートを提供し、アプリケーション開発を容易にします。
Spring を使用する利点
Spring フレームワークを使用する利点については上で詳しくリストしましたが、2 番目の点についてのみ詳しく説明します。 Spring フレームワークを使用すると、コンテナーによって提供される多数のサービスを使用できます。
Spring フレームワークを使用しない場合、トランザクション操作に Hibernate フレームワークを使用するには、次のようにする必要があると想像してください。
Hibernate トランザクション操作:
public void save(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Info info = new Info("Spring框架"); info.setContent("阿昀手把手教你学习Spring框架"); session.save(info); session.getTransaction().commit(); }
Spring フレームワークも Hibernate フレームワークも使用されず、最も原始的な JDBC テクノロジがトランザクション操作に直接使用されます。コードは次のようになります:
JDBC トランザクション操作:
Connection conn = null; try { ...... conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate("update person where name='叶天'"); conn.commit(); ...... } catch (Exception e) { conn.rollback(); } finally { conn.close(); }
Spring フレームワークを使用する場合、トランザクションを手動で制御する必要はなくなります。さらに、Spring フレームワークを使用すると、複雑なトランザクション伝播動作に対処する必要がなくなります。これを例で説明してみましょう。
(ビデオチュートリアルの推奨: java コース)
たとえば、次のコードがあります:
public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录操作日志 }
public class Bean1 { public void update(){ // 注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { public void save(){ // 注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate("insert into Log (content) values (?)"); } }
Spring フレームワークを使用しない場合、次の 2 つのビジネス ニーズがある場合、どうすればよいでしょうか?
最初に考えられるビジネス要件: Bean1.update() と Bean2.save() を同じトランザクションで実行する必要があります。
ビジネス要件の 2 つ目: Bean1.update() のトランザクションが成功したかどうかに関係なく、操作ログを記録する必要があります。
Spring フレームワークを使用しない場合、最初の考えられるビジネス要件については、ソリューションはコードで表現されます:
public void payment(){ Connection conn = null; conn.setAutoCommit(false); Bean1.update(conn); // 更新金额 Bean2.save(conn); // 记录操作日志 // ...提交或回滚事务 }
public class Bean1 { public void update(Connection conn){ // 注意:下面省略了一些代码 Statement.executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { public void save(Connection conn){ // 注意:下面省略了一些代码 Statement.executeUpdate("insert into Log (content) values (?)"); } }
2 番目に考えられるビジネス要件については、使用しません。完了できます。 Bean1.update() がトランザクションをオープンし、Bean2.save() もトランザクションをオープンするため、コードを変更することで、Bean1.update() によって開始されたトランザクションのロールバックは、Bean2.save() でオープンされたトランザクションには影響しません。
Spring フレームワークを使用すると、宣言的なトランザクション属性の構成を通じてこれら 2 つのビジネス要件を簡単に達成できます。
Bean1.update() と Bean2.save() を同じトランザクションで実行する必要があります。コードを次のように変更するだけです:
@Transactional(propagation=Propagation.Required) public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录日志 }
public class Bean1 { @Transactional(propagation=Propagation.Required) public void update(){ executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { @Transactional(propagation=Propagation.Required) public void save(){ executeUpdate("insert into Log (content) values (?)"); } }
Bean1.update() トランザクションが成功したかどうかに関係なく、ログを記録する必要があります。コードを次のように変更するだけです:
@Transactional(propagation=Propagation.Required) public void payment(){ Bean1.update(); // 更新金额 Bean2.save(); // 记录日志 }
public class Bean1 { @Transactional(propagation=Propagation.Required) public void update(){ executeUpdate("update account set amount=? where id=?"); } }
public class Bean2 { @Transactional(propagation=Propagation.RequiresNew) public void save(){ executeUpdate("insert into Log (content) values (?)"); } }
軽量概念と重量概念の分割
Spring は軽量フレームワークなのか、それとも重量フレームワークなのか、よく尋ねられます。実際、アプリケーションが軽量または重量に分類されるかどうかは、主にアプリケーションが使用するサービスの数によって決まります。使用されるサービスが増えるほど、コンテナが通常の Java オブジェクトに対して実行する必要がある作業が増え、必然的にアプリケーションのリリース時間や実行パフォーマンスに影響が生じます。
Spring コンテナの場合、多くのサービスが提供されますが、これらのサービスはデフォルトではアプリケーションによって開かれません。アプリケーションは特定のサービスを必要とし、その使用を指定する必要があります。アプリケーションが Spring コア サービスのみを使用するなど、非常に少数のサービスを使用する場合、そのアプリケーションは軽量であると見なすことができます。アプリケーションが Spring によって提供されるサービスのほとんどを使用する場合、アプリケーションはヘビーウェイトです。現在の EJB コンテナは、デフォルトで EJB 仕様のすべての機能をアプリケーションに提供するため、重量が大きくなります。
以上が春とは何か知っていますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。