Java – requires pattern advice (hibernate Guice)

I am looking for advice on how to inject runtime dependencies into JPA entities retrieved from hibernate My question is basically this:

I have some different subclasses of transaction objects Each transaction subclass has different behavior when executing, and needs a set of dependencies different from the environment These transaction objects are managed by hibernate as a JPA entity, so I can't effectively use Guice for dependency injection to populate instances with environment dependencies, just as I do in other applications

To solve this problem, I adopted a method similar to visitor mode, as follows:

public abstract class Transaction {
    // ...snip...
    public abstract void apply(Transactor transactor);
}

public class TransactionA extends Transaction {
    public void apply(Transactor transactor) {
        transactor.execute(this);
    }
}

public class TransactionB extends Transaction {
    public void apply(Transactor transactor) {
        transactor.execute(this);
    }
}
// other Transaction subclasses with the same boilerplate

public interface Transactor {
    public void execute(TransactionA trans);
    public void execute(TransactionB trans);
    // corresponding methods for other transaction types.
}

public class BeginTransactor {
     @Inject
     private Foo execAdep;
     public void execute(TransactionA trans) {
         execAdep.doSomething(...)    
     }

     @Inject
     private Bar execBdep;
     public void execute(TransactionB trans) {
         execBdep.doOther(...)    
     }
 }

I provide various transactor implementations for different parts of the transaction lifecycle These can be injected into the context of the transaction I want to process using Guice dependency injection. I just need to call:

Transactor transactor = injector.getInstance(BeginTransactor.class); //Guice injection
 Transaction t = ... //get a transaction instance
 t.apply(transactor);

What I don't like about this method is that (1) not every type of transaction should be executable at each life cycle stage, but each transactor must implement an execute () method for each transaction subclass, and (2) there are basically no injected dependencies for processing multiple transaction types

Basically, my transactor interface & implementation has a lot of unrelated cruds together Ideally, I have only the execute () method on the transaction object itself, but I don't want the calling code to know the type of transaction or its required dependencies In addition, this may make the test more difficult, because if it is a concrete method of the transaction object, I can't easily simulate the execute () method Using the transactor interface means that I can easily simulate it as needed

Anyone can suggest how to solve this problem in a type safe way, which will not lead to a pile of mostly irrelevant behavior in transactor, but maintain testability and allow dependency injection?

Solution

I use Guice to trade, but I use AOP to execute them I had little model and sacrificed a little "magic" As long as the course you intercepted is "in the club", it can work well

class BusinessLogic {
    @Inject public EntityManager em;

    @Transactional
    publc void doSomething() {
       //...
       em.persist(myObj);
    }

    @Transactional
    public void doSomethingElse() {
       //...
       em.delete(myObj);
    }
}

class TransactionalInterceptor implements MethodInterceptor {
    @Inject static Injector injector;
    public Object intercept(MethodInvocation invocation) {
        EntityManager em = injector.getInstance(EntityManager.class);
        em.getTransaction().begin();
        Object result = invocation.proceed();
        em.getTransaction().commit();
        return result;
    }
}
class TransactionalModule extends AbstractModule {
    public void configure() {
        requestStaticInjection(TransactionalInterceptor.class);
        bindInterceptor(Matchers.any(),Matchers.annotatedWith(Transactional.class),new TransactionalInterceptor());
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>