栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++11 Aspect自实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++11 Aspect自实现

想加个类似spring里面的AOP,避免插桩式的编码,也方便代码复用。

虽然有AspectC++这个现成的轮子,但是看下了下也是静态的,根据AspectC++对应的语法使用自己的编译器编译的时候替换成C++代码语法,不是我想要的,引入是个麻烦事。

那就只能自己造了,写了一点,写的不怎么满意,只能说先凑活用,做不到JAVA那么灵活,先记录下来吧,后面有精力看看怎么完善吧。

以下只对C++11,如果有C++17,可以用 if constexpr 去掉下面重复的模板函数匹配,一坨参数匹配,写着难受看着难受。


#include 
#include 
#include 
#include 
#include 
#include 

template 
class HasAfterFunc {
    template 
    static auto test(int) -> decltype(std::declval().after(std::declval()...), std::true_type());
    template 
    static std::false_type test(...);

public:
    enum {
        value = std::is_same::value
    };
};

template 
class HasBeforeFunc {
    template 
    static auto test(int) -> decltype(std::declval().before(std::declval()...), std::true_type());
    template 
    static std::false_type test(...);

public:
    enum {
        value = std::is_same::value
    };
};


template
class AspectWeaver
{
  public:
    template 
    typename std::enable_if::value && HasBeforeFunc::value && !HasAfterFunc::value>::type
    addAspect(std::shared_ptr aspect)
    {

        m_beforeList.push_back([aspect](Args &&...args) { aspect->before(std::forward(args)...); });
    }

    template 
    typename std::enable_if::value && HasBeforeFunc::value &&
                            HasAfterFunc::value>::type
    addAspect(std::shared_ptr aspect)
    {
        m_beforeList.push_back([aspect](Args &&...args) { aspect->before(std::forward(args)...); });
        m_afterList.push_front([aspect](Args &&...args) { aspect->after(std::forward(args)...); });
    }

    template 
    typename std::enable_if::value && HasAfterFunc::value && !HasBeforeFunc::value >::type
    addAspect(std::shared_ptr aspect)
    {
        m_afterList.push_front([aspect](Args &&...args) { aspect->after(std::forward(args)...); });
    }

    template 
    auto invoke(FuncType &&func, Args... args) -> decltype(std::declval()(args...))
    {
        for (auto iter : m_beforeList)
        {
            iter(args...);
        }
        auto r = func(args...);
        for (auto iter : m_afterList)
        {
            iter(args...);
        }
        return r;
    }

    private:
    std::list> m_beforeList;
    std::list> m_afterList;
};

#include 
class MyClass {
public:
    int func(int i)
    {
        i = i*i;
        std::cout << i << std::endl;
        return 0;
    }

    int func1(int i)
    {
        i += 1;
        std::cout << "this func1 " << i << std::endl;
        return 0;
    }
};

class Aspect1 {
public:
    void before(int i)
    {
        std::cout << "Aspect1 before" << std::endl;
    }
};

class Aspect2 {
public:
    void after(int i)
    {
        std::cout << "Aspect2 after" << std::endl;
    }
};

class Aspect3 {
public:
    void before(int i)
    {
        std::cout << "Aspect3 begin" << std::endl;
    }

    void after(int i)
    {
        std::cout << "Aspect3 end" << std::endl;
    }
};

int main(){
    AspectWeaver weaver;
    weaver.addAspect(std::make_shared());
    weaver.addAspect(std::make_shared());
    weaver.addAspect(std::make_shared());

    MyClass a;
    weaver.invoke(std::bind(&MyClass::func, &a, std::placeholders::_1), 1);

    weaver.invoke([&a](int PH1) { return a.func1(std::forward(PH1)); }, 1);
}

输出

Aspect1 before
Aspect3 begin
1
Aspect3 end
Aspect2 after
Aspect1 before
Aspect3 begin
this func1 2
Aspect3 end
Aspect2 after

此外还有参考网上 另外一种更静态的实现


#include 
#include 
#include 
#include 
#include 
#include 

template 
class HasAfterFunc {
    template 
    static auto test(int) -> decltype(std::declval().after(std::declval()...), std::true_type());
    template 
    static std::false_type test(...);

public:
    enum {
        value = std::is_same::value
    };
};

template 
class HasBeforeFunc {
    template 
    static auto test(int) -> decltype(std::declval().before(std::declval()...), std::true_type());
    template 
    static std::false_type test(...);

public:
    enum {
        value = std::is_same::value
    };
};

template 
struct Aspect {
    Aspect(Func&& f)
        : m_func(std::forward(f))
    {
    }

    template 
    typename std::enable_if::value && HasAfterFunc::value>::type Invoke(Args&&... args, T&& aspect)
    {
        aspect.before(std::forward(args)...); //核心逻辑之前的切面逻辑
        m_func(std::forward(args)...); //核心逻辑
        aspect.after(std::forward(args)...); //核心逻辑之后的切面逻辑
    }

    template 
    typename std::enable_if::value && !HasAfterFunc::value>::type Invoke(Args&&... args, T&& aspect)
    {
        aspect.before(std::forward(args)...); //核心逻辑之前的切面逻辑
        m_func(std::forward(args)...); //核心逻辑
    }

    template 
    typename std::enable_if::value && HasAfterFunc::value>::type Invoke(Args&&... args, T&& aspect)
    {
        m_func(std::forward(args)...); //核心逻辑
        aspect.after(std::forward(args)...); //核心逻辑之后的切面逻辑
    }

    template 
    typename std::enable_if::value && HasAfterFunc::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
    {

        headAspect.before(std::forward(args)...);
        Invoke(std::forward(args)..., std::forward(tailAspect)...);
        headAspect.after(std::forward(args)...);
    }

    template 
    typename std::enable_if::value && HasAfterFunc::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
    {

        Invoke(std::forward(args)..., std::forward(tailAspect)...);
        headAspect.after(std::forward(args)...);
    }

    template 
    typename std::enable_if::value && !HasAfterFunc::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
    {
        headAspect.before(std::forward(args)...);
        Invoke(std::forward(args)..., std::forward(tailAspect)...);
    }

private:
    Func m_func; //被织入的函数
};

template 
using identity_t = T;

// AOP的辅助函数,简化调用
template 
void Invoke(Func&& f, Args&&... args)
{
    Aspect asp(std::forward(f));
    asp.Invoke(std::forward(args)..., identity_t()...);
}

#include 

class MyClass {
public:
    int func(int i)
    {
        i = i * i;
        std::cout << i << std::endl;
        return 0;
    }

    int func1(int i)
    {
        i += 1;
        std::cout << "this func1 " << i << std::endl;
        return 0;
    }
};

class Aspect1 {
public:
    void before(int i)
    {
        std::cout << "Aspect1 before" << std::endl;
    }
};

class Aspect2 {
public:
    void after(int i)
    {
        std::cout << "Aspect2 after" << std::endl;
    }
};

class Aspect3 {
public:
    void before(int i)
    {
        std::cout << "Aspect3 begin" << std::endl;
    }

    void after(int i)
    {
        std::cout << "Aspect3 end" << std::endl;
    }
};

int main()
{
    MyClass a;

    Invoke(std::bind(&MyClass::func, &a, std::placeholders::_1), 1);
    Invoke([&a](int PH1) { return a.func1(std::forward(PH1)); }, 1);
}

输出一致

Aspect1 before
Aspect3 begin
1
Aspect3 end
Aspect2 after
Aspect1 before
Aspect3 begin
this func1 2
Aspect3 end
Aspect2 after
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/821022.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号