SCA(Tuscany) implementation.spring 源码分析

项目要求集成SCA(Tuscany),还要结合Spring使用(把Spring容器管理的ServiceBean公开为SCA服务),问题是SCA有自己独立的容器,直接访问Spring容器内部的Beans比较困难,因为它们不在同一容器内。所以简单研究了下代码,改一下Tuscany源码,直接访问Spring容器中的Beans,这样的话 事务包装 也可以直接通过Spring解决了

图:


修改的源码片段:
org.apache.tuscany.sca.implementation.spring.runtime.context
...
public SpringContextTie(SpringImplementationStub implementation, List<URL> resource, boolean annotationSupport, String versionSupported) throws Exception {
...
        // edit by fengjc
//        springContext = createApplicationContext(scaParentContext, resource);
        springContext = (AbstractApplicationContext) org.springframework.web.context.ContextLoader.getCtx();
        // end
    }


或许改源码不是好的解决方式,但是项目需求就这样,没办法,暂时找不到更好的解决办法
另外,在Tuscany中取得ApplicationContext的代码:
org.springframework.web.context.ContextLoader.getCtx();

也是修改了Spring的ContextLoader.java的代码
getCtx()返回ApplicationContext的引用,罪过,这块不是我改的,我实在觉得改源码不好

补充:修改org.apache.tuscany.sca.implementation.spring.invocation.SpringInvoker
中的如下代码可以生成class文件(只适合JDK Proxy的情况),使用反编译软件查看Spring生成的代理类
    // Lazy-load the method to avoid timing problems with the Spring Context
    private void setupMethod() throws SpringInvocationException{
        try {
            bean = springContext.getBean(beanElement.getId());
            // add by fengjc for test
            {
                byte[] proxyClassFile = sun.misc.ProxyGenerator.generateProxyClass(
                        bean.getClass().getName(),
                        bean.getClass().getInterfaces());
                
                System.out.println(bean.getClass().getName());
                try {
                    FileOutputStream fos = new FileOutputStream(new File(bean.getClass().getName() + ".class"));
                    fos.write(proxyClassFile, 0, proxyClassFile.length);
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // end
            Class<?> beanClass = bean.getClass();

如果Spring是使用CGLIB生成的代理类,请参考CGLIB源码,net.sf.cglib.core.AbstractClassGenerator类中的如下代码:
byte[] b = strategy.generate(this);
  

猜你喜欢

转载自budairenqin.iteye.com/blog/1522272
SCA