zoukankan      html  css  js  c++  java
  • Tapestry IoC Service

    Services

    可以在AppModule类中追加如下方法:

    public static SomeInterface build(){
        return new SomeInterfaceImpl();
    }

    我们的方法可以使build,也可以是以build开头的方法,如buildSomething。

    还有一种更为推荐的方式为使用

    public static void bind(ServiceBinder binder){
        binder.bind(SomeInterface.class, SomeInterfaceImpl.class);
    }

    甚至,如果一个接口跟它的实现类在一个package下的话,并且实现类的名字为接口的名字+impl的话,可以省略掉后一个参数,如:

    public static void bind(ServiceBinder binder){ binder.bind(SomeInterface.class); } 

    Service Id

    每一个Service都有一个名字,默认的名字就是Service的class名称,如果修改的话,可以使用@ServiceId注解

    @ServiceId("FileSystemIndexer")
    public static Indexer buildIndexer(@InjectService("FileSystem") FileSystem fileSystem)
    {
       . . .
    }

    另外一种就是

    public static Indexer buildFileSystemIndexer(@InjectService("FileSystem") FileSystem fileSystem)
    {
       . . .
    }

    还有一种

    @ServiceId("FileSystemIndexer")
    public class IndexerImpl implements Indexer
    {
        ...
    }

    // Module.class
    binder.bind(Indexer.class, IndexerImpl.class);

    还有另外一种:

    binder.bind(Indexer.class, IndexerImpl.class).withId("FileSystemIndexer");

    HOLLY SHIT! SO MANY KINDS OF METHODS RESULT IN I DON'T KNOW WHICH TO CHOOSE.

    Service之间可能是相互依赖的,如我们有一个Service,它的实现需要用到别的Service,这时需要按照如下方法进行服务的注册:

    public static Indexer build(JobScheduler scheduler, FileSystem fileSystem)
    {
      IndexerImpl indexer = new IndexerImpl(fileSystem);
      scheduler.scheduleDailyJob(indexer);
      return indexer;
    }

    如果我们依赖的Service有多个实现,那么我们就需要用到@ServiceId这个注解了:

    public static Indexer build(@InjectService("JobScheduler")JobScheduler scheduler,  @InjectService("FileSystem")FileSystem fileSystem)
    {
      IndexerImpl indexer = new IndexerImpl(fileSystem);
      scheduler.scheduleDailyJob(indexer);
      return indexer;
    }

    如果有多个Service依赖了另外同一个Service的话,我们可以给module类追加一个构造器,并且把这个被依赖的Service作为它的构造参数。

    @Marker

    可以通过设定自定义的注解来帮助Tapestry去定位一个服务的实现。小猿没啥兴趣~

    Tapestry有一个自定义的Marker——@Local,它会告诉Tapestry只允许找自己这个module中的实现~

    advise

    这是用来给service追加一些建议,保证的东西。

    例如:给某些想要返回一个String类型的值得service方法追加一个判断,如果返回的是一个NULL的话,就返回一个空字符串

    public static void adviseNonNull(MethodAdviceReceiver receiver) {
    ...
    }

    这里面有几个问题

    1 这个方法的返回值是void,且是static的。

    2 这个方法的适用范围没有设定,所以追加适用范围@Match("*")或@Match("*DAO")。

    3 建议内容没有设定,所以追加建议内容,是以内部类的方式来实现的,

    MethodAdvice advice = new MethodAdvice(){
        void advice(MethodInvocation invocation){
            // 首先方法运行
            invocation.proceed();
            // 可以得到结果了,如果是null的话
            if (getReturnValue().equals(null)) {
                 invocation.setReturnValue("");
            }
        }
    }

    没有任何问题,什么时候触发这个advice呢?

    4 设定触发条件,返回类型是String的时候。

            for (Method method : receiver.getInterface().getMethods()) {
                if (method.getReturnType().equals(String.class)) {
                    receiver.adviseMethod(method, advice);
                }
            }

    所以结合起来:

        /**
         * If the return value, of the method of some service, is null, then set it into ""
         */
        @Match("*")
        public static void adviseNonNull(MethodAdviceReceiver receiver) {
    
            MethodAdvice advice = new MethodAdvice() {
    
                public void advise(MethodInvocation invocation) {
                    invocation.proceed();
    
                    if (invocation.getReturnValue().equals(null)) {
                        invocation.setReturnValue("");
                    }
                }
            };
    
            // for those method of services of which the return type is String.class
            // Add the advice above
            for (Method method : receiver.getInterface().getMethods()) {
                if (method.getReturnType().equals(String.class)) {
                    receiver.adviseMethod(method, advice);
                }
            }
    
        }

    其它的一些advise

    // LOG ADDING
    @Match("*") public static void adviseLogging(LoggingAdvisor loggingAdvisor, Logger logger, MethodAdviceReceiver receiver) { loggingAdvisor.addLoggingAdvice(logger, receiver); }
    // 所有DAO下面的service方法中如果标记了@CommitAfter就会自动将把业务提交
    @Match("*Dao") public static void adviseTransactions(HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver) { advisor.addTransactionCommitAdvice(receiver); }
  • 相关阅读:
    Working with macro signatures
    Reset and Clear Recent Items and Frequent Places in Windows 10
    git分支演示
    The current .NET SDK does not support targeting .NET Core 2.1. Either target .NET Core 2.0 or lower, or use a version of the .NET SDK that supports .NET Core 2.1.
    Build website project by roslyn through devenv.com
    Configure environment variables for different tools in jenkins
    NUnit Console Command Line
    Code Coverage and Unit Test in SonarQube
    头脑王者 物理化学生物
    头脑王者 常识,饮食
  • 原文地址:https://www.cnblogs.com/voctrals/p/3778215.html
Copyright © 2011-2022 走看看