Call a method any time other methods are called

后端 未结 5 459
傲寒
傲寒 2021-01-04 11:19

Is there any way to make a sort of \"supermethod\" that is called every time a method is called, even for non-defined methods? Sort of like this:

public void         


        
相关标签:
5条回答
  • 2021-01-04 11:44

    I guess that it is not exactly what you want, but you could wrap all code in methods into try {}finally {supermethod ()}. That would garantuee that supermethod is called.

    0 讨论(0)
  • 2021-01-04 11:48

    The Term behind this concept is called interceptor. You need a container that does this like a ApplicationServer, CDI Container, Spring or AOP. It works like this

    1. call your Method
    2. pause your Method
    3. call intercepter
    4. do interceptor stuff
    5. resume your Method inside the interceptor
    
    0 讨论(0)
  • 2021-01-04 11:51

    Sure you can do this, not with standard java but with AspectJ

    Here is a simple example:

    Aspect with an after-advice

    package net.fsa.aspectj.test;
    
    
    public aspect SuperMethdAspect {
    
        pointcut afterPointCut() : execution(public * com.my.pack.age.MyClass.*(..));
    
        after() : afterPointCut() {
            System.out.println("Super");
        }
    }
    

    You target class

    package com.my.pack.age;
    
    public class MyClass {
    
        public void onStart() {
            System.out.println("Start");
        }
    
        public void onEnd() {
            System.out.println("End");
        }
    }
    

    And finally some test app

    package net.fsa.aspectj.test;
    
    import com.my.pack.age.MyClass;
    
    public class MyApp {
    
        public static void main(String... args) {
            MyClass myClass = new MyClass();
            myClass.onStart();
            myClass.onEnd();
        }
    }
    

    Output

    Start
    Super
    End
    Super
    
    0 讨论(0)
  • 2021-01-04 11:54

    Java doesn't really allow magic like this. In order for a call to happen, it has to appear within your (compiled) code. So the answer is no, not without explicitly adding a call to the relevant methods. However, you can hide that somewhat by using a preprocessor or runtime code generation.

    I think AspectJ might be what you want.

    0 讨论(0)
  • 2021-01-04 11:57

    Here is an implementation in pure Java using the Proxy class:

    import java.lang.reflect.*;
    import java.util.*;
    
    public class Demo
    {
        public static void main(String[] args)
        {
            Map<String, String> map = new HashMap<String, String>();
            map.put("onStart", "abc");
            map.put("onEnd", "def");
            Library library = new LibraryProxy(map, new LibraryImpl()).proxy();
            library.onStart();
            library.onEnd();
            library.onRun();
        }
    }
    
    interface Library
    {
        void onStart();
        void onEnd();
        void onRun();
    }
    
    class LibraryImpl
    {
        public void abc() { System.out.println("Start"); }
        public void def() { System.out.println("End"); }
    }
    
    class LibraryProxy implements InvocationHandler
    {
        Map<String, String> map;
        Object impl;
    
        public LibraryProxy(Map<String, String> map, Object impl)
        {
            this.map = map;
            this.impl = impl;
        }
    
        public Library proxy()
        {
            return (Library) Proxy.newProxyInstance(Library.class.getClassLoader(),
                new Class[] { Library.class }, this);
        }
    
        @Override
        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
        {
            Object res = null;
            String name = map.get(m.getName());
            if (name == null) {
                System.out.println("[" + m.getName() + " is not defined]");
            } else {
                m = impl.getClass().getMethod(name, m.getParameterTypes());
                res = m.invoke(impl, args);
            }
            System.out.println("super duper");
            return res;
        }
    }
    

    Output:

    Start
    super duper
    End
    super duper
    [onRun is not defined]
    super duper
    
    0 讨论(0)
提交回复
热议问题