LaravelとSpringBootでDIコンテナを利用してみる
はじめに
これはユアマイスターAdventCalendar2019の13日目の記事です。
(社会人になってから学んだことをアウトプットする記事になります。)
今回の経緯
社会人になってからDI(依存性の注入)という概念を知りました。
WEBサービスの開発を行う際に、フレームワークを利用する場面は多々ありましたが、主に利用していたCake PHP
ではDIという概念は出ていなかったと記憶しています。
(記憶違いだったらすみません。)
DIは、インスタンスをnewで作成して利用するのではなく、DIコンテナやサービスコンテナ呼ばれるもの(SpringBootではDIコンテナ、Laravelではサービスコンテナと呼ばれます)を利用して、あらかじめ登録されたインスタンスを利用します。
今回は、業務で利用しているSpringBootでのDIコンテナの利用、最近独学で学んでいるLaravelでのサービスコンテナを利用してみるというテーマで記事を書いてみたいと思います。
SpringBootの場合
コンストラクターインジェクションを利用する
ユアマイスターアドベントカレンダー2019 の7日目の記事で書いたコードを用いて書いていきます。
SpringBootで動的にDBを切り替えてみる
https://github.com/Masaki-Ogawa/datasourceDemo
- PersonRepository.java
package com.example.dataSourceDemo.domain.repositories;
import com.example.dataSourceDemo.domain.models.Person;
import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}
JpaRepositoryを継承したRepositoryクラス
- PersonServiceImpl.java
package com.example.dataSourceDemo.domain.services;
import com.example.dataSourceDemo.annotations.DataSource;
import com.example.dataSourceDemo.annotations.DataSource.DataSourceType;
import com.example.dataSourceDemo.domain.models.Person;
import com.example.dataSourceDemo.domain.repositories.PersonRepository;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class PersonServiceImpl implements PersonService {
private final PersonRepository personRepository;
public PersonServiceImpl(
PersonRepository personRepository) {
this.personRepository = personRepository;
}
/**
* stgのDBからPersonテーブルのレコードを取得するメソッド
* @return Personテーブルのレコード
*/
@Override
public List<Person> findAllPersonInStg() {
return personRepository.findAll();
}
/**
* stgのDBからPersonテーブルのレコードを取得するメソッド
* @return Personテーブルのレコード
*/
@DataSource(value = DataSourceType.PROD)
@Override
public List<Person> findAllPersonInProd() {
return personRepository.findAll();
}
}
ここでDIを行っています。
具体的には、
private final PersonRepository personRepository;
public PersonServiceImpl(
PersonRepository personRepository) {
this.personRepository = personRepository;
}
の部分でコンストラクターインジェクションによるDIを行っています。
@Service
や@Repository
というアノテーションを利用することにより、DIコンテナに登録されます。
利用するには上記のように、コンストラクターインジェクション等を利用して、インスタンスを作成します。
参考
Spring Framework 要点まとめ ~ DIについて
LaravelでのDI
サービスプロバイダーを利用する
作成したサービスをサービスコンテナ登録するためのサービスプロバイダーを作成します。
今回はDemoServiceというサービスクラスを作成しました。
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind('App\Services\DemoService');
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
}
上記のようにサービスを登録します。
class DemoService {
public function show() {
echo "何かを表示します";
}
}
サービスクラスは今回は適当ですが、何か文字を出力するメソッドのみ実装します。
class MessageController extends Controller
{
protected $demoService;
public function __construct(DemoService $demoService)
{
$this->demoService = $demoService;
}
public function index(Request $request) {
return $this->demoService->show();
}
}
このようにこちらもコンストラクターインジェクションを利用して、こちらもDIを行います。
終わりに
個人的には、@Service
や@Controller
等のアノテーションで、DIコンテナに登録できるSpringBootの方が利用しやすいと感じています。
Java、SpringBootを利用してやはり、アノテーションの強力さに気づかされる場面が多々あります。
また、7日目のアドベントカレンダーで書きましたが、それぞれのフレームワークに良さや悪さがあり、多数のフレームワークに触るという経験は、今後何かものを作るときに、「どんなものを採用すれば、そのプロダクトにとって一番良いのか?」という判断材料になると思います。
今後も、業務、業務外を含めて触れていきたいと思います。
Author And Source
この問題について(LaravelとSpringBootでDIコンテナを利用してみる), 我々は、より多くの情報をここで見つけました https://qiita.com/masaki-ogawa/items/12564c3689baa7ea4292著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .