想加个类似spring里面的AOP,避免插桩式的编码,也方便代码复用。
虽然有AspectC++这个现成的轮子,但是看下了下也是静态的,根据AspectC++对应的语法使用自己的编译器编译的时候替换成C++代码语法,不是我想要的,引入是个麻烦事。
那就只能自己造了,写了一点,写的不怎么满意,只能说先凑活用,做不到JAVA那么灵活,先记录下来吧,后面有精力看看怎么完善吧。
以下只对C++11,如果有C++17,可以用 if constexpr 去掉下面重复的模板函数匹配,一坨参数匹配,写着难受看着难受。
/*
* @Author: shanRX
* @Date: 2022-02-24 15:23:06
* @LastEditTime: 2022-02-28 10:01:00
* @LastEditors: shanRX
* @Description: 切面编织
* 咸鱼本咸
*/
#include <functional>
#include <list>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
template <typename T, typename... Args>
class HasAfterFunc {
template <typename C = T>
static auto test(int) -> decltype(std::declval<C>().after(std::declval<Args>()...), std::true_type());
template <typename C = T>
static std::false_type test(...);
public:
enum {
value = std::is_same<decltype(test(0)),
std::true_type>::value
};
};
template <typename T, typename... Args>
class HasBeforeFunc {
template <typename C = T>
static auto test(int) -> decltype(std::declval<C>().before(std::declval<Args>()...), std::true_type());
template <typename C = T>
static std::false_type test(...);
public:
enum {
value = std::is_same<decltype(test(0)),
std::true_type>::value
};
};
template<typename... Args>
class AspectWeaver
{
public:
template <typename AspectType>
typename std::enable_if<std::is_class<AspectType>::value && HasBeforeFunc<AspectType, Args...>::value && !HasAfterFunc<AspectType, Args...>::value>::type
addAspect(std::shared_ptr<AspectType> aspect)
{
m_beforeList.push_back([aspect](Args &&...args) { aspect->before(std::forward<Args>(args)...); });
}
template <typename AspectType>
typename std::enable_if<std::is_class<AspectType>::value && HasBeforeFunc<AspectType, Args...>::value &&
HasAfterFunc<AspectType, Args...>::value>::type
addAspect(std::shared_ptr<AspectType> aspect)
{
m_beforeList.push_back([aspect](Args &&...args) { aspect->before(std::forward<Args>(args)...); });
m_afterList.push_front([aspect](Args &&...args) { aspect->after(std::forward<Args>(args)...); });
}
template <typename AspectType>
typename std::enable_if<std::is_class<AspectType>::value && HasAfterFunc<AspectType, Args...>::value && !HasBeforeFunc<AspectType, Args...>::value >::type
addAspect(std::shared_ptr<AspectType> aspect)
{
m_afterList.push_front([aspect](Args &&...args) { aspect->after(std::forward<Args>(args)...); });
}
template <typename FuncType>
auto invoke(FuncType &&func, Args... args) -> decltype(std::declval<FuncType>()(args...))
{
for (auto iter : m_beforeList)
{
iter(args...);
}
auto r = func(args...);
for (auto iter : m_afterList)
{
iter(args...);
}
return r;
}
private:
std::list<std::function<void(Args...)>> m_beforeList;
std::list<std::function<void(Args...)>> m_afterList;
};
#include <iostream>
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<int> weaver;
weaver.addAspect(std::make_shared<Aspect1>());
weaver.addAspect(std::make_shared<Aspect2>());
weaver.addAspect(std::make_shared<Aspect3>());
MyClass a;
weaver.invoke(std::bind(&MyClass::func, &a, std::placeholders::_1), 1);
weaver.invoke([&a](int PH1) { return a.func1(std::forward<decltype(PH1)>(PH1)); }, 1);
}
输出
Aspect1 before
Aspect3 begin
1
Aspect3 end
Aspect2 after
Aspect1 before
Aspect3 begin
this func1 2
Aspect3 end
Aspect2 after
此外还有参考网上 另外一种更静态的实现
/*
* @Author: shanRX
* @Date: 2022-02-24 15:23:06
* @LastEditTime: 2022-02-28 10:01:00
* @LastEditors: shanRX
* @Description: 切面编织
* 咸鱼本咸
*/
#include <functional>
#include <list>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
template <typename T, typename... Args>
class HasAfterFunc {
template <typename C = T>
static auto test(int) -> decltype(std::declval<C>().after(std::declval<Args>()...), std::true_type());
template <typename C = T>
static std::false_type test(...);
public:
enum {
value = std::is_same<decltype(test(0)),
std::true_type>::value
};
};
template <typename T, typename... Args>
class HasBeforeFunc {
template <typename C = T>
static auto test(int) -> decltype(std::declval<C>().before(std::declval<Args>()...), std::true_type());
template <typename C = T>
static std::false_type test(...);
public:
enum {
value = std::is_same<decltype(test(0)),
std::true_type>::value
};
};
template <typename Func, typename... Args>
struct Aspect {
Aspect(Func&& f)
: m_func(std::forward<Func>(f))
{
}
template <typename T>
typename std::enable_if<HasBeforeFunc<T, Args...>::value && HasAfterFunc<T, Args...>::value>::type Invoke(Args&&... args, T&& aspect)
{
aspect.before(std::forward<Args>(args)...); //核心逻辑之前的切面逻辑
m_func(std::forward<Args>(args)...); //核心逻辑
aspect.after(std::forward<Args>(args)...); //核心逻辑之后的切面逻辑
}
template <typename T>
typename std::enable_if<HasBeforeFunc<T, Args...>::value && !HasAfterFunc<T, Args...>::value>::type Invoke(Args&&... args, T&& aspect)
{
aspect.before(std::forward<Args>(args)...); //核心逻辑之前的切面逻辑
m_func(std::forward<Args>(args)...); //核心逻辑
}
template <typename T>
typename std::enable_if<!HasBeforeFunc<T, Args...>::value && HasAfterFunc<T, Args...>::value>::type Invoke(Args&&... args, T&& aspect)
{
m_func(std::forward<Args>(args)...); //核心逻辑
aspect.after(std::forward<Args>(args)...); //核心逻辑之后的切面逻辑
}
template <typename Head, typename... Tail>
typename std::enable_if<HasBeforeFunc<Head, Args...>::value && HasAfterFunc<Head, Args...>::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
{
headAspect.before(std::forward<Args>(args)...);
Invoke(std::forward<Args>(args)..., std::forward<Tail>(tailAspect)...);
headAspect.after(std::forward<Args>(args)...);
}
template <typename Head, typename... Tail>
typename std::enable_if<!HasBeforeFunc<Head, Args...>::value && HasAfterFunc<Head, Args...>::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
{
Invoke(std::forward<Args>(args)..., std::forward<Tail>(tailAspect)...);
headAspect.after(std::forward<Args>(args)...);
}
template <typename Head, typename... Tail>
typename std::enable_if<HasBeforeFunc<Head, Args...>::value && !HasAfterFunc<Head, Args...>::value>::type Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect)
{
headAspect.before(std::forward<Args>(args)...);
Invoke(std::forward<Args>(args)..., std::forward<Tail>(tailAspect)...);
}
private:
Func m_func; //被织入的函数
};
template <typename T>
using identity_t = T;
// AOP的辅助函数,简化调用
template <typename... AP, typename... Args, typename Func>
void Invoke(Func&& f, Args&&... args)
{
Aspect<Func, Args...> asp(std::forward<Func>(f));
asp.Invoke(std::forward<Args>(args)..., identity_t<AP>()...);
}
#include <iostream>
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<Aspect1,Aspect2,Aspect3>(std::bind(&MyClass::func, &a, std::placeholders::_1), 1);
Invoke<Aspect1,Aspect2,Aspect3>([&a](int PH1) { return a.func1(std::forward<decltype(PH1)>(PH1)); }, 1);
}
输出一致
Aspect1 before
Aspect3 begin
1
Aspect3 end
Aspect2 after
Aspect1 before
Aspect3 begin
this func1 2
Aspect3 end
Aspect2 after