zoukankan      html  css  js  c++  java
  • [译]在Java中使用JavaScript作为依赖注入容器

    大多数Java开发人员是因为DI与AOP的需要而使用Spring的.Spring通常有冗长的XML配置.普通的JDK可以使用动态代理来处理AOP,这篇文章演示了使用JavaScript处理依赖注入.

    Java 6起,Java应用程序可以在其JVM实例调用脚本语言,使用脚本API无缝地与脚本进行通信. Sun公司的JRE附带一个内置的引擎,通过这个API处理Javasript.我们可以利用Javascript的强大表现力JVM之执行一些很酷的东西.

    我们要创建什么?

    1.两个DAO接口和它们的模拟实现.

    2.使用这些DAO的一个service示例.

    3.JS脚本将它们连接到一起.

    4.一个对service方法调用进行记录的简单拦截器.

    DAO接口与实现:

    package dao;
    
    public interface BooksDAO {
        public int count();
    }
    
    
    package dao;
    
    public interface MembersDAO {
        public int count();
    }
    
    
    package dao;
    
    public class MockBooksDAO implements BooksDAO {
    
        @Override
        public int count() {
            return 500;
        }
    }
    
    
    package dao;
    
    public class MockMembersDAO implements MembersDAO {
    
        @Override
        public int count() {
            return 100;
        }
    }

    Service接口与实现:

    package service;
    
    public interface LibraryService {
    
        public abstract int countBooks();
    
        public abstract int countMembers();
    
    }
    
    
    package service;
    
    import dao.BooksDAO;
    import dao.MembersDAO;
    
    public class MockLibraryService implements LibraryService {
        private BooksDAO booksDAO;
        private MembersDAO membersDAO;
    
        public MockLibraryService(BooksDAO booksDAO, MembersDAO membersDAO) {
            this.booksDAO = booksDAO;
            this.membersDAO = membersDAO;
        }
    
        public int countBooks() {
            System.out.println("In countBooks()");
            return booksDAO.count();
        }
    
        public int countMembers() {
            System.out.println("In countMembers()");
            return membersDAO.count();
        }
    }

    依赖注入脚本:

    我们利用JavaScript的Object直接量定义并组织DAOs与services.我们可以从应用程序中查找到这些以获得具体的实现.

    src/objects.js

    importPackage(Packages.dao)
    importPackage(Packages.service)
    importPackage(Packages.interceptor)
    
    daos = {
     booksDAO : new MockBooksDAO(),
     membersDAO : new MockMembersDAO()
    }
    
    services = {
     libraryService : LoggingInterceptor.getProxy(new MockLibraryService(daos.booksDAO, daos.membersDAO))
    }

    应用程序代码:

    我们使用ScriptEngineBuilder对Javacript求值,并从中获取service示例.

    package app;
    
    import javax.script.ScriptEngine;
    import javax.script.ScriptException;
    
    import service.LibraryService;
    import util.ScriptEngineBuilder;
    
    public class Main {
        public static void main(String[] args) throws ScriptException {
            ScriptEngine engine = new ScriptEngineBuilder("js").add("/objects.js").build();
    
            LibraryService service = (LibraryService) engine.eval("services.libraryService");
    
            System.out.println("Found " + service.countMembers() + " Members!");
            System.out.println("Found " + service.countBooks() + " Members!");
        }
    }

    添加AOP到组合中

    创建JDK动态代理来记录所有方法调用

    package interceptor;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class LoggingInterceptor implements InvocationHandler {
        private Object target;
    
        public static Object getProxy(Object target) {
            ClassLoader loader = LoggingInterceptor.class.getClassLoader();
            Class[] interfaces = target.getClass().getInterfaces();
            InvocationHandler handler = new LoggingInterceptor(target);
            
            return Proxy.newProxyInstance(loader, interfaces, handler);
        }
    
        private LoggingInterceptor(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            try {
                System.out.println("Entered Method: " + method.getName());
                Object val = method.invoke(target, args);
                System.out.println("Completed Method: " + method.getName());
                return val;
            } catch (Exception e) {
                System.out.println("Exception in Method: " + method.getName());
                throw e;
            }
        }
    
    }

    现在,我们可以修改依赖注入脚本,利用代理改变service的创建方式

    libraryService : LoggingInterceptor.getProxy(new MockLibraryService(daos.booksDAO, daos.membersDAO))

    到此,我们有了一个非常好的干净的包含AOP的依赖注入配置方案,且不需要任何Java SE之外的东西.这里要记住的一个重点是,与使用注解不同,我们仍须在应用程序代码之外维护DIAOP的配置.Spring需要一卡车XML来达到同样的目的.

    原文:http://blog.tuxychandru.com/2009/08/using-javascript-as-di-container-in.html

  • 相关阅读:
    C语言32个关键字详解
    C语言格式控制符
    c++关键字详解
    多码流简介
    Jtag管脚定义
    关于RGB信号的电平
    缩略语MSPS
    【转】松下18650的容量判别方法
    电信号在FR4材料中的传播速度
    dropout voltage
  • 原文地址:https://www.cnblogs.com/fangzhaolee/p/2839975.html
Copyright © 2011-2022 走看看