src/plugins/AopPlugin.js
/**
* @file aop插件
* @author exodia(d_xinxin@163.com)
*/
import BasePlugin from './BasePlugin';
/**
* @private
* @ignore
*/
export default class AopPlugin extends BasePlugin {
static AOP_COMPONENT_CONFIG = {
module: 'uaop',
scope: 'static'
};
static AOP_ID = Symbol('internalAop');
get name() {
return 'aop';
}
/**
* @override
*/
onContainerInit(ioc, iocConfig) {
ioc.addComponent(this.constructor.AOP_ID, this.constructor.AOP_COMPONENT_CONFIG);
return iocConfig;
}
/**
* 是否需要代理
*
* @param {Object} config 配置
* @param {string} type 代理类型[class|object]
* @return {boolean}
*/
canProxy(config, type) {
if (!('aopConfig' in config)) {
return false;
}
// 默认代理对象为 object
let {proxyTarget = 'object'} = config.aopConfig;
return proxyTarget === type;
}
/**
* 类或对象代理过程
*
* @param {IoC} ioc ioc 实例
* @param {string} type 代理类型[class|object]
* @param {Function} initial 待拦截的类或对象
* @param {Array.<Object>} [advisors=[]] 切面
* @return {Promise.<Object | Class>}
*/
proxyAop(ioc, type, initial, advisors = []) {
const METHOD = type === 'class' ? 'createClassProxy' : 'createObjectProxy';
const AOP_ID = this.constructor.AOP_ID;
return ioc.getComponent(AOP_ID).then(
aop => advisors.reduce(
(target, {matcher, advices}) => aop[METHOD](target, matcher, advices),
initial
)
);
}
/**
* @override
*/
beforeCreateInstance(ioc, componentId, instance) {
let config = ioc.getComponentConfig(componentId) || {};
let proxyTarget = 'class';
if (this.canProxy(config, proxyTarget)) {
return this
.proxyAop(ioc, proxyTarget, config.creator, config.aopConfig.advisors)
.then(ProxyClass => config.creator = ProxyClass)
.then(() => instance);
}
return Promise.resolve(instance);
}
/**
* @override
*/
afterCreateInstance(ioc, componentId, instance) {
let config = ioc.getComponentConfig(componentId) || {};
let proxyTarget = 'object';
return this.canProxy(config, proxyTarget)
? this.proxyAop(ioc, proxyTarget, instance, config.aopConfig.advisors)
: Promise.resolve(instance);
}
}