`

编译器加载的AOP实现

    博客分类:
  • aop
阅读更多
public class MapClassLoader extends ClassLoader
{
    private Map<String, byte[]> classes;
    
    public MapClassLoader(Map<String, byte[]> classes)
    {
        this.classes = classes;
    }
    
    protected Class<?> findClass(String name)
        throws ClassNotFoundException
    {
        byte[] classBytes = classes.get(name);
        if (classBytes == null)
            throw new ClassNotFoundException(name);
        Class<?> cl = this.defineClass(name, classBytes, 0, classBytes.length);
        if (cl == null)
            throw new ClassNotFoundException(name);
        return cl;
    }
}

 

package compile;



public abstract class ButtonFrame extends JFrame
{
    private static final long serialVersionUID = 1L;
    
    protected JPanel panel;
    
    public static final int DEFAULT_WIDTH = 300;
    
    public static final int DEFAULT_HEIGHT = 200;
    
    protected JButton yellowButton;
    
    protected JButton blueButton;
    
    protected JButton redButton;
    
    public ButtonFrame()
    {
        this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        panel = new JPanel();
        add(panel);
        yellowButton = new JButton("Yellow");
        blueButton = new JButton("Blue");
        redButton = new JButton("Red");
        
        panel.add(yellowButton);
        panel.add(blueButton);
        panel.add(redButton);
        addEventHandlers();
    }
    
    protected abstract void addEventHandlers();
}

 StringBuilderJavaSource 

//字符串源文件类,源文件类的重构
public class StringBuilderJavaSource extends SimpleJavaFileObject
{
    private StringBuilder code;
    
    public StringBuilderJavaSource(String name)
    {
        super(URI.create("string:////" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
        code = new StringBuilder();
    }
    
    public CharSequence getCharContent(boolean ignoreEncodingErrors)
    {
        return code;
    }
    
    public void append(String str)
    {
        code.append(str);
        code.append("\n");
    }
}

 

ByteArrayJavaClass

package compile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;

import javax.tools.SimpleJavaFileObject;

//字节源文件构造
public class ByteArrayJavaClass extends SimpleJavaFileObject
{
    private ByteArrayOutputStream stream;
    
    protected ByteArrayJavaClass(String name)
    {
        super(URI.create("byte:///" + name), Kind.CLASS);
        this.stream = new ByteArrayOutputStream();
    }
    
    public OutputStream openOutputStream()
        throws IOException
    {
        return stream;
    }
    
    public byte[] getBytes()
    {
        return stream.toByteArray();
    }
    
}

 

action.properties文件内容   

  

yellowButton=panel.setBackground(java.awt.Color.YELLOW);   

blueButton=panel.setBackground(java.awt.Color.BLUE);   

redButton=panel.setBackground(java.awt.Color.RED);   

 

编译器测试类

public class CompilerTest
{
    public static void main(String[] args)
        throws IOException
    {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        final List<ByteArrayJavaClass> classFileObjects = new ArrayList<ByteArrayJavaClass>();
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
        JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
        
        fileManager = new ForwardingJavaFileManager<JavaFileManager>(fileManager)
        {
            
            @Override
            public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
                FileObject sibling)
                throws IOException
            {
                if (className.startsWith("x."))
                {
                    ByteArrayJavaClass fileObject = new ByteArrayJavaClass(className);
                    classFileObjects.add(fileObject);
                    return fileObject;
                }
                else
                    return super.getJavaFileForOutput(location, className, kind, sibling);
            }
        };
        JavaFileObject source = buildSource("compile.ButtonFrame");
        JavaCompiler.CompilationTask task = compiler.getTask(null,
            fileManager,
            diagnostics,
            null,
            null,
            Arrays.asList(source));
        Boolean result = task.call();
        for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics())
            System.out.println(d.getKind() + ": " + d.getMessage(null));
        fileManager.close();
        if (!result)
        {
            System.out.println("Compilation failed");
            System.exit(1);// 退出系统运行,挺有意思的,虽然我做的东西不经常用。。。
        }
        EventQueue.invokeLater(new Runnable()
        {
            
            public void run()
            {
                try
                {
                    Map<String, byte[]> byteCodeMap = new HashMap<String, byte[]>();
                    for (ByteArrayJavaClass cl : classFileObjects)
                        byteCodeMap.put(cl.getName().substring(1), cl.getBytes());
                    ClassLoader loader = new MapClassLoader(byteCodeMap);
                    Class<?> cl = loader.loadClass("x.Frame");
                    JFrame frame = (JFrame)cl.newInstance();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setTitle("CompilerTest");
                    frame.setVisible(true);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                
            }
            
        });
    }
    
    // 建立源文件类
    static JavaFileObject buildSource(String superclassName)
        throws IOException
    {
        StringBuilderJavaSource source = new StringBuilderJavaSource("x.Frame");
        source.append("package x;\n");
        source.append("public class Frame extends " + superclassName + " {");
        source.append("protected void addEventHandlers(){");
        Properties props = new Properties();
        props.load(new FileReader("src\\compile\\action.properties"));
        for (Map.Entry<Object, Object> e : props.entrySet())
        {
            String beanName = (String)e.getKey();
            String eventCode = (String)e.getValue();
            source.append(beanName + ".addActionListener(new java.awt.event.ActionListener(){");
            source.append("public void actionPerformed(java.awt.event.ActionEvent event){");
            source.append(eventCode);
            source.append("}});");
        }
        source.append("}}");
        return source;
    }
}

 

分享到:
评论

相关推荐

    spring源代码分析:aop的实现

    在编译时,AspectJ编译器会将这些注解转换为AspectJ语言的切面,然后在运行时由Spring AOP加载和应用。 总的来说,Spring的AOP机制通过动态代理技术,实现了对横切关注点的透明化处理,降低了系统的复杂度。通过对...

    aop所依赖的所有包

    AspectJ Weaver通常与Spring AOP一起使用,Spring AOP则是Spring框架提供的轻量级AOP实现。 AOP Alliance是一个接口集,定义了AOP框架之间的通用API,使得不同的AOP实现能够互操作。它定义了一些基础的切面接口,如...

    多种AOP实现方式及产品简介

    分别记录JavaAop在不同阶段的不同实现方式和产品如编译器静态植入的Aspectj、运行时字节码加载前的Javasist、字节码加载后动态代理织入的Proxy等等方式和产品。

    Spring Aop四个依赖的Jar包

    4. **aopalliance-1.0.jar**:AOP Alliance是一个包含AOP领域通用接口的库,旨在促进不同AOP实现之间的互操作性。Spring AOP就是基于这些接口进行设计的,因此这个库是Spring AOP和其他AOP实现之间协作的基础。 在...

    实现AOP功能的jar包

    AspectJ Weaver通常用于实现运行时织入,而AspectJ编译器可以处理编译时织入。 通过理解以上概念和机制,开发者可以利用Spring AOP有效地管理和组织代码,提高代码的可复用性和可维护性,同时降低系统的复杂度。

    Spring3.2 AOP extra jar

    这些jar包包含了对AOP实现至关重要的组件和类库,例如AspectJ、CGLIB和Apache Commons Logging等。 首先,我们来看`aspectj-1.7.2-src.jar`,这是AspectJ的源码包。AspectJ是一个强大的Java语言扩展,它允许开发者...

    aop开发环境jar包

    当我们谈到“AOP开发环境jar包”时,通常是指一组能够支持AOP编程的库和工具,这些库包括Spring框架中的AOP模块或其他AOP实现。 描述中的“这个不会出现jar包版本不匹配问题,我可是弄了一天啊”可能意味着发布者...

    aspectj-aspectjweaver-aopalliance

    AspectJ是Java平台上的一个开源AOP框架,而AOPAlliance则是为不同的AOP实现提供一个共同接口的标准库。在这个压缩包中,我们看到了三个重要的组件:`aspectj.jar`、`aspectjweaver.jar`和`aopalliance.jar`,它们都...

    Springframework核心技术AOP详细介绍文档.pdf

    AspectJ是一种更全面的AOP实现,它不仅提供了在运行时织入增强的方式,还支持编译期和加载期的织入方式,而Spring AOP是与Spring框架高度集成的,并主要面向企业级应用中常见的AOP需求,例如方法执行的织入。...

    aop@work.rar

    AOP的核心思想是将这些关注点从主业务逻辑中分离出来,实现代码的模块化和解耦。 1. AOP的基本概念: - 切面(Aspect):AOP的核心单元,包含了横切关注点的定义,可以理解为一个模块化的功能集合。 - 连接点...

    spring aop注解所需要的三个jar包,aspectjrt.jar,aspectjweaver.jar,aopalliance.jar

    在Spring中,许多Spring AOP的通知类型(如Before、After、Around等)都是基于AOP Alliance的接口实现的,这使得开发者可以在不关心具体AOP实现的情况下编写通用的拦截器和通知。 这三个JAR包在Spring AOP中的角色...

    aopalliance+aspectjrt+aspectjweaver

    本资源包含的"aopalliance+aspectjrt+aspectjweaver"是一组完整的AOP实现所需的jar包,它们在网络上的资源相对较少,因此显得尤为珍贵。 1. **aopalliance.jar**:这是AOP联盟提供的一个库,它定义了通用的AOP接口...

    jboss aop

    JBoss AOP支持使用注解编译器,针对JDK 1.4版本,该编译器支持注解、枚举类型、注解内嵌注解等功能,简化了AOP的配置过程。 #### 安装 JBoss AOP的安装可以通过独立安装或与JBoss 4.x应用服务器集成两种方式实现,...

    spring aop必须jar包

    1.0.jar**:这是一个通用的AOP接口库,由AOP Alliance组织提供,定义了与AOP相关的通用接口,如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,使得不同的AOP实现可以互相协作。...

    spring-aop实例

    Spring支持三种织入时机:编译时(使用AspectJ编译器)、加载时(使用AspectJ LTW)和运行时(由Spring容器处理)。 9. **应用场景**:Spring AOP常用于日志记录、事务管理、性能监控、安全性控制等。例如,你可以...

    Spring AOP依赖jar包

    - **aspectjweaver.jar**:AspectJ 编译器和织入器,负责在类加载时进行织入。 3. **配置 Spring AOP** 在 Spring 配置文件中,需要启用 AOP 并配置切面。以下是一个基本示例: ```xml xmlns:xsi=...

    aopalliance_java_

    在Java世界里,AOP通常用于实现诸如日志记录、性能监控、事务管理等横切关注点,从而提高代码的模块化和可维护性。 AOP Alliance的核心在于它的接口,这些接口定义了如何声明和执行切面。其中最著名的接口包括`org....

    AOP的AspectJ实现方案来做语言切换

    在AOP的实现方式中,AspectJ是最强大且功能丰富的,尽管它的学习曲线相对陡峭,但其强大的编译时织入和运行时织入能力使其成为专业开发者的首选。 AspectJ是一个独立的AOP框架,它提供了一种静态类型的、基于Java的...

    AOP的jar包

    AspectJ提供了一个编译器和一个加载器,可以处理注解和编织切面。在Spring AOP中,AspectJ的 weaving 功能使得可以在运行时动态地将切面应用到目标类,增强了灵活性。 **3. CGLIB库** `cglib-nodep-2.1_3.jar`是...

Global site tag (gtag.js) - Google Analytics