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); }
  • 相关阅读:
    按照鬼哥学so变化,四,第一章的例子
    浏览器发送总共下载文件2第二个请求,如何“下载”仅仅记录1次要?
    hdu 3371 Connect the Cities
    自己写RTPserver——大约RTP协议
    cocos2d-x3.2中将XCode发展project转移到VS2010可能会发生错误
    apache kafkac系列lient发展-java
    大约++和--了解运营商
    socket计划——一个简单的例子
    PhotoShop基本工具 -- 移动工具
    ZA7783:MIPI转LVDS/MIPI转RGB888/RGB转LVDS
  • 原文地址:https://www.cnblogs.com/voctrals/p/3778215.html
Copyright © 2011-2022 走看看