?Wath:AOP是什么?
- 面向切面编程(Aspect Oriented Programming)一种编程思想
- OOP(面向对象编程)与AOP区别
? - OOP针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分管理。 ? - AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果 ? - OOP负责抽象和管理,AOP负责解耦和复用 ? - OOP面向名词领域,AOP面向动词领域 ? - OOP面向纵向,AOP面向横向
AOP术语
术语 | 说明 |
---|
切面 | 切面泛指交叉业务逻辑。比如事物处理,日志处理就可以理解为切面。 | 织入 | 织入是指将切面代码插入到目标对象的过程 | 连接点 | 连接点指切面可以织入的位置 | 切入点 | 切入点指切面具体织入的位置 |
Why:为啥要使用AOP?
- 降低业务耦合度 - 提高程序可复用性 - 提高代码可读性,易维护性 - 提高开发效率
Where:什么地方使用AOP?
- 日志记录 - 性能统计 - 安全控制 - 事务处理 - 异常处理 - 多模块调用的公共组件
?How :python中一般怎么使用AOP?
- @ 装饰器 - with上下文管理器
- 案例
? - 打开sql日志,性能分析简易版装饰器
import logging
import time
from functools import partial, wraps
from django.utils.decorators import ContextDecorator
logger = logging.getLogger(__name__)
class SqlLogger(ContextDecorator):
"""
SQL日志管理
装饰器用法:
@SqlLogger
def
"""
def __init__(self, is_open=True):
self.is_open = is_open
self.sql_logger = logging.getLogger("django.db.backends")
self.level = self.sql_logger.level
self.stream_handler = logging.StreamHandler()
def __enter__(self):
if self.is_open:
self.sql_logger.setLevel("DEBUG")
self.sql_logger.addHandler(self.stream_handler)
def __exit__(self, exc_type, exc_val, exc_tb):
if self.is_open:
self.sql_logger.setLevel(self.level)
self.sql_logger.removeHandler(self.stream_handler)
def sql_log(func=None):
if callable(func):
return SqlLogger()(func)
else:
return SqlLogger(func)
@sql_log
def test_1():
from itsm.ticket.models.ticket import Ticket
Ticket.objects.first()
def fn_performance(
func=None,
log=logger,
threshold=0.5,
stack_info=False,
level=logging.DEBUG,
notify="",
message="[fn: {fn_name}] [func: {func}] [timer: {time}]",
show_param=True,
open_sql=False,
**kwargs,
):
if func is None:
return partial(
fn_performance,
log=log,
level=level,
message=message,
notify=notify,
threshold=threshold,
stack_info=stack_info,
show_param=show_param,
open_sql=open_sql
)
@wraps(func)
def wrapper(*real_args, **real_kwargs):
t0 = time.time()
with sql_log(open_sql):
result = func(*real_args, **real_kwargs)
interval = round(time.time() - t0, 5)
nonlocal log
nonlocal threshold
log.log(
level,
"<Performance Log> {} {} ".format(notify,
message.format(fn_name=func.__name__, time=interval,
func=func)),
)
if interval >= threshold:
if show_param:
log.log(
logging.WARNING,
"The [func_name: {fn_name}] [func: {func}] "
"[args:{realfn_args}] [kwargs: {realfn_kwargs}] "
"[timer:{time}s] [threshold:{threshold}s], please timely optimize.".format(
fn_name=func.__name__,
func=func,
time=interval,
realfn_args=real_args,
realfn_kwargs=real_kwargs,
threshold=threshold,
),
stack_info=stack_info,
)
else:
log.log(
logging.WARNING,
"The [func_name: {fn_name}] [func: {func}] "
"[timer:{time}s] [threshold:{threshold}s], please timely optimize.".format(
fn_name=func.__name__, func=func, time=interval, threshold=threshold
),
stack_info=stack_info,
)
return result
return wrapper
|