Springの紹介-AOP

以下からの内容で、Baiduの百科事典
AOPあるAspect Oriented Programming頭字語の意味:アスペクト指向プログラミング、動的に事前にコンパイルされ、実行モード中に機関によって実装統一プログラムの機能を維持するための技術。AOPあるOOP継続は、ソフトウェア開発のホットスポットですが、また、Springフレームワークの重要な要素は、関数型プログラミングYanshengファンタイプです。この使用AOPにより、ビジネスロジックのさまざまな部分を分離できるため、ビジネスロジックのさまざまな部分間の結合が減り、プログラムの再利用性が向上し、同時に開発の効率が向上します。

1.静的プロキシ

プロジェクト開発の過程で、そのような合意された考えがあります:機能の拡張は、元の機能を変更せずに拡張する必要があります。次に、第3号のエージェントを紹介する必要がありますこの種の考え方Service、前のレイヤーよりよく実現されています。たとえば、特定のServiceImplクラス展開する必要がある場合は、このServiceインターフェイスを実装するための追加のクラスを記述してから、追加する必要のあるコードを追加できます。このタイプのプロキシは静的プロキシでもあります。たとえば、次の例:
ここに画像の説明を挿入

public interface UserDao {
    
    
    String getUserName();
}

public class UserDaoImpl implements UserDao{
    
    
    public String getUserName() {
    
    
        return "张三";
    }
}

public interface UserService {
    
    
    String getUserInfo();
}

public class UserServiceImpl implements UserService{
    
    
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
    
    
        this.userDao = userDao;
    }

    public String getUserInfo() {
    
    
        return userDao.getUserName();
    }
}

たとえば、この時点でテストします。

@Test
public void getUserInfoTest(){
    
    
    UserServiceImpl userService = new UserServiceImpl();
    userService.setUserDao(new UserDaoImpl());
    System.out.println(userService.getUserInfo());
}

ここに画像の説明を挿入
そこに行くgetUserInfoたびに追加情報照会する必要がある場合は、プロキシクラスを使用してこれを実行する必要があります。

public class proxy implements UserService {
    
    

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
    
    
        this.userDao = userDao;
    }

    public String getUserInfo() {
    
    
        doSomething();
        return userDao.getUserName();
    }

    private void doSomething() {
    
    
        System.out.println("做一些事情");
    }
}
@Test
public void getUserInfoTest(){
    
    
    proxy userServiceProxy = new proxy();
    userServiceProxy.setUserDao(new UserDaoImpl());
    System.out.println(userServiceProxy.getUserInfo());
}

ここに画像の説明を挿入
このアイデアは、アダプタモードと同様に、主に元のコードを変更せずに一部の関数を追加するのに適しています。これは、静的プロキシモードとも呼ばれます。このアプローチの主な欠点は、場合ということですAB結果はコードの重複の多くを書くことで明らかである、...それのすべてがカスタマイズされて、複数のプロキシクラスを追加しました。したがって、ここでは動的プロキシモードを導入する必要があります。

2.動的プロキシ

現時点では、いくつかの新しい関数を追加するときに、多くのクラスを追加したり、多くの反復コードを追加したりしないことを望んでいます。ここで使用する必要があるテクニックJavaは、真ん中の反射です。
動的エージェントは、次の2つのカテゴリに分類できます。

  • インターフェイスベース-JDK動的プロキシ。
  • クラスベース–cglib;
  • Javaバイトコードの実装。

使用する必要がInvocationHandlerあり、Proxy2つのクラス:

  • InvocationHandler:ハンドラーを呼び出して結果を返します。
  • Proxy:動的プロキシのこのインスタンスを生成するために使用される動的プロキシクラスとインスタンスを作成するための静的メソッドを提供します。

この時点で、プロキシクラスを削除してから、動的プロキシを実装proxyするためのInvocationHandlerインターフェイスを実装するクラスを作成します。
まず、今回のニーズを明確にするかService、エージェントを使って行う必要のあるレイヤーの機能を拡張します。

public class MyInvocationHandler implements InvocationHandler {
    
    
	
	// 需要扩充的接口对象【或者,需要代理的接口对象】
    UserService userService;

    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    // 生成代理类对象,也就是需要扩充的接口对象UserService
    public Object getProxy(){
    
    
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                userService.getClass().getInterfaces(), this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        // 新增功能调用
        doSomethings();
        // 传入需要动态代理的对象
        return method.invoke(userService, args);
    }
    
	// 这里是扩充内容
    private void doSomethings(){
    
    
        System.out.println("做一些事情。");
    }
}

テストするには、前のServiceImplセクションで次のような文印刷することをお勧めします

public class UserServiceImpl implements UserService{
    
    
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
    
    
        this.userDao = userDao;
    }

    public String getUserInfo() {
    
    
        System.out.println("以前的getUserInfo接口的扩充");
        return userDao.getUserName();
    }
}

テスト:

@Test
public void getUserInfoTest(){
    
    
    UserServiceImpl userService = new UserServiceImpl();
    userService.setUserDao(new UserDaoImpl());
    MyInvocationHandler handler = new MyInvocationHandler();
    handler.setUserService(userService);
    // 新的UserService对象,实现了新增功能,但是我们这里并没有去真的用类来创建
    UserService userService1 = (UserService) handler.getProxy();
    System.out.println(userService1.getUserInfo());
}

ここに画像の説明を挿入
つまり、UserServiceImpl今回は元のプロジェクトのクラス変更せず、プロジェクトの実行時に元のgetUserInfo関数が呼び出され、要件の新しい関数が呼び出されました。

  • 動的プロキシクラスは、対応するインターフェイスが実装されている限り、複数のクラスをプロキシできます。
  • プロキシがインターフェースである動的プロキシクラス、プロキシは一種のビジネスです。

ビデオアドレス:https//www.bilibili.com/video/BV1WE411d7Dv?p = 19

おすすめ

転載: blog.csdn.net/qq_26460841/article/details/115054727