ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Portable Service Abstraction (PSA)
    Framework/SPRING 2020. 3. 6. 09:47

    1. Overview

    Spring Framework helps implementing technical aspects of the application like security and transactions in a declarative way by providing annotations to capture settings for those aspects. When creating the object tree, it then decorates the instance

    2. Example

    2.1 Security and Transactions

    Spring components using services like security and transactions

    @Component
    class MyService {
    
      private final MyRepository repository;
    
      …
    
      @PreAuthorize("hasRole('ADMIN')") // 1
      void someBusinessMethod(…) {
        this.repository.save(new MyEntity());
      }
    }
    
    @Component
    class JpaRepository implements MyRepository {
    
      @Transactional // 2
      MyEntity save(MyEntity entity) { … }
    }
    • @PreAuthorize("hasRole('ADMIN')"): Express that someBusinessMethod(…) is supposed to be only used by administrators.
    • @Transactional: Expresses that all database operations happening within save(…) are supposed to be transactional, i.e. atomic.

    Note, how we don’t have to write code ourselves that makes all this happen. We just declare what we want to happen and the framework takes care of actually implementing it. It’s also worth mentioning that the annotations are the only Spring dependencies of the code, i.e. there’s only a very thin connection between user code and the framework.

    2.1.1 Implementation

    The application of the technical services is implemented using the proxy pattern in which a proxy for the target component is generated at runtime. A chain of interceptors is computed at bootstrap time and handles the technical concerns (in this particular case the management of a transaction). The framework creates an instance of the target component enriched with additional functionality and injects that into the client component. This can only be achieved as the client component avoids an active lookup or creation of the collaborating component itself.

    Note, how MyRepositoryProxy implements MyRepository so that it can act as a replacement for the user provided JpaRepository within MyService.

    The actual implementation is created by Spring Framework’s ProxyFactory that makes it easy to decorate target instances with generic MethodInterceptor implementations that use of Aspect-oriented Programming (AOP) and reflection at runtime.

    class TransactionInterceptor implements MethodInterceptor {
    
      @Override
      public Object invoke(MethodInvocation invocation) throws Throwable {
    
        // Start transaction
        Transaction transaction = …
    
        try {
    
          Object result = invocation.proceed(); // 1
    
          transaction.commit()
    
          return result;
    
        } catch (RuntimeException e) {
          transaction.rollback()
          throw e;
        }
      }
    }
    
    // Wrapping the application component into a transactional proxy
    JpaRepository repository = new JpaRepository();
    ProxyFactory factory = new ProxyFactory(repository);
    factory.addAdvice(new TransactionInterceptor());
    
    MyRepository proxy = factory.getProxy();

    invocation.proceed() triggers all other interceptors in the chain and the invocation of the method on the final target instance eventually.

    3. Reference

    https://www.slideshare.net/etagowni/spring-introduction-54000363

    https://abn-abn.tistory.com/189

    http://static.olivergierke.de/lectures/spring/#spring.psa

    https://jins-dev.tistory.com/entry/Spring-PSAPortable-Service-Abstraction%EC%9D%98-%EA%B0%9C%EB%85%90

    'Framework > SPRING' 카테고리의 다른 글

    Bean Definition Overriding  (0) 2020.05.23
    Application Context  (0) 2020.04.10
    Dependency Injection (DI)  (0) 2020.03.05
    Spring Inversion of Control (IoC)  (0) 2020.02.06
    Spring Framework  (0) 2020.02.06

    댓글

Designed by Tistory.