Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
希川
container-mini
提交
bbce0776
C
container-mini
项目概览
希川
/
container-mini
通知
6
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
container-mini
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bbce0776
编写于
11月 04, 2021
作者:
希川
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
<feat>: 将AOP代理功能集成进管理容器中
上级
b2c9e023
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
313 addition
and
0 deletion
+313
-0
src/main/java/cn/noexception/container/aop/AdvisedSupport.java
...ain/java/cn/noexception/container/aop/AdvisedSupport.java
+11
-0
src/main/java/cn/noexception/container/aop/Advisor.java
src/main/java/cn/noexception/container/aop/Advisor.java
+17
-0
src/main/java/cn/noexception/container/aop/BeforeAdvice.java
src/main/java/cn/noexception/container/aop/BeforeAdvice.java
+12
-0
src/main/java/cn/noexception/container/aop/MethodBeforeAdvice.java
...java/cn/noexception/container/aop/MethodBeforeAdvice.java
+16
-0
src/main/java/cn/noexception/container/aop/PointcutAdvisor.java
...in/java/cn/noexception/container/aop/PointcutAdvisor.java
+11
-0
src/main/java/cn/noexception/container/aop/aspectj/AspectJExpressionPointcutAdvisor.java
...ntainer/aop/aspectj/AspectJExpressionPointcutAdvisor.java
+45
-0
src/main/java/cn/noexception/container/aop/framework/ProxyFactory.java
.../cn/noexception/container/aop/framework/ProxyFactory.java
+30
-0
src/main/java/cn/noexception/container/aop/framework/adapter/MethodBeforeAdviceInterceptor.java
.../aop/framework/adapter/MethodBeforeAdviceInterceptor.java
+31
-0
src/main/java/cn/noexception/container/aop/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
...p/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
+81
-0
src/main/java/cn/noexception/container/factory/config/InstantiationAwareBeanPostProcessor.java
...r/factory/config/InstantiationAwareBeanPostProcessor.java
+16
-0
src/test/java/cn/noexception/test/ApiRunner.java
src/test/java/cn/noexception/test/ApiRunner.java
+8
-0
src/test/java/cn/noexception/test/bean/UserServiceBeforeAdvice.java
...ava/cn/noexception/test/bean/UserServiceBeforeAdvice.java
+18
-0
src/test/resources/config_aop.xml
src/test/resources/config_aop.xml
+17
-0
未找到文件。
src/main/java/cn/noexception/container/aop/AdvisedSupport.java
浏览文件 @
bbce0776
...
...
@@ -9,6 +9,9 @@ import org.aopalliance.intercept.MethodInterceptor;
* @Date 2021/11/3 14:46
*/
public
class
AdvisedSupport
{
private
boolean
proxyTargetClass
=
false
;
// 被代理的目标对象
private
TargetSource
targetSource
;
// 方法拦截器
...
...
@@ -16,6 +19,14 @@ public class AdvisedSupport {
// 方法匹配器(检查目标方法是否符合通知条件)
private
MethodMatcher
methodMatcher
;
public
boolean
isProxyTargetClass
()
{
return
proxyTargetClass
;
}
public
void
setProxyTargetClass
(
boolean
proxyTargetClass
)
{
this
.
proxyTargetClass
=
proxyTargetClass
;
}
public
TargetSource
getTargetSource
()
{
return
targetSource
;
}
...
...
src/main/java/cn/noexception/container/aop/Advisor.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop
;
import
org.aopalliance.aop.Advice
;
/**
* Advisor
* 定义访问者
* <p>
* Advisor 承担了 Pointcut 和 Advice 的组合,
* Pointcut 用于获取 JoinPoint,而 Advice 决定于 JointPoint 执行什么操作
* </p>
* @author 吕滔
* @Date 2021/11/4 16:17
*/
public
interface
Advisor
{
Advice
getAdvice
();
}
src/main/java/cn/noexception/container/aop/BeforeAdvice.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop
;
import
org.aopalliance.aop.Advice
;
/**
* BeforeAdvice
*
* @author 吕滔
* @Date 2021/11/4 15:18
*/
public
interface
BeforeAdvice
extends
Advice
{
}
src/main/java/cn/noexception/container/aop/MethodBeforeAdvice.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop
;
import
java.lang.reflect.Method
;
/**
* MethodBeforeAdvice
*
* @author 吕滔
* @Date 2021/11/4 16:07
*/
public
interface
MethodBeforeAdvice
extends
BeforeAdvice
{
/**
* 给定方法调用之前的回调
*/
void
before
(
Method
method
,
Object
[]
args
,
Object
target
)
throws
Throwable
;
}
src/main/java/cn/noexception/container/aop/PointcutAdvisor.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop
;
/**
* PointcutAdvisor
*
* @author 吕滔
* @Date 2021/11/4 16:27
*/
public
interface
PointcutAdvisor
extends
Advisor
{
Pointcut
getPointcut
();
}
src/main/java/cn/noexception/container/aop/aspectj/AspectJExpressionPointcutAdvisor.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop.aspectj
;
import
cn.noexception.container.aop.Pointcut
;
import
cn.noexception.container.aop.PointcutAdvisor
;
import
org.aopalliance.aop.Advice
;
/**
* AspectJExpressionPointcutAdvisor
* <p>
* 实现了 PointcutAdvisor 接口,把切面、拦截方法和具体拦截表达式包装在一起。</br>
* 这样就可以在 xml 的配置中定义一个 pointcutAdvisor 切面拦截器了。
* </p>
*
* @author 吕滔
* @Date 2021/11/4 16:30
*/
public
class
AspectJExpressionPointcutAdvisor
implements
PointcutAdvisor
{
// 切面
private
AspectJExpressionPointcut
pointcut
;
// 具体的拦截方法
private
Advice
advice
;
// 表达式
private
String
expression
;
public
String
getExpression
()
{
return
expression
;
}
public
void
setAdvice
(
Advice
advice
)
{
this
.
advice
=
advice
;
}
@Override
public
Advice
getAdvice
()
{
return
advice
;
}
@Override
public
Pointcut
getPointcut
()
{
if
(
null
==
pointcut
)
{
pointcut
=
new
AspectJExpressionPointcut
(
expression
);
}
return
pointcut
;
}
}
src/main/java/cn/noexception/container/aop/framework/ProxyFactory.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop.framework
;
import
cn.noexception.container.aop.AdvisedSupport
;
/**
* ProxyFactory<p>
* - 代理工厂类,用于解决关于选择Cglib 和 JDK 两种代理的问题<p>
* - 有了代理工厂就可以安札不同的创建需求进行控制
*
* @author 吕滔
* @Date 2021/11/4 16:43
*/
public
class
ProxyFactory
{
private
AdvisedSupport
advisedSupport
;
public
ProxyFactory
(
AdvisedSupport
advisedSupport
)
{
this
.
advisedSupport
=
advisedSupport
;
}
public
Object
getProxy
()
{
return
createAopProxy
().
getProxy
();
}
private
AopProxy
createAopProxy
()
{
if
(
advisedSupport
.
isProxyTargetClass
())
{
return
new
Cglib2AopProxy
(
advisedSupport
);
}
return
new
JdkDynamicAopProxy
(
advisedSupport
);
}
}
src/main/java/cn/noexception/container/aop/framework/adapter/MethodBeforeAdviceInterceptor.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop.framework.adapter
;
import
cn.noexception.container.aop.MethodBeforeAdvice
;
import
org.aopalliance.intercept.MethodInterceptor
;
import
org.aopalliance.intercept.MethodInvocation
;
/**
* MethodBeforeAdviceInterceptor
* - 方法拦截器
* @author 吕滔
* @Date 2021/11/4 16:34
*/
public
class
MethodBeforeAdviceInterceptor
implements
MethodInterceptor
{
private
MethodBeforeAdvice
advice
;
public
MethodBeforeAdviceInterceptor
(
MethodBeforeAdvice
advice
)
{
this
.
advice
=
advice
;
}
/**
* 实现了 MethodInterceptor 接口,调用 advice 中的 before 方法,传入对应的参数信息。
* @param invocation
* @return
* @throws Throwable
*/
@Override
public
Object
invoke
(
MethodInvocation
invocation
)
throws
Throwable
{
this
.
advice
.
before
(
invocation
.
getMethod
(),
invocation
.
getArguments
(),
invocation
.
getThis
());
return
invocation
.
proceed
();
}
}
src/main/java/cn/noexception/container/aop/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.aop.framework.autoproxy
;
import
cn.noexception.container.BeansException
;
import
cn.noexception.container.aop.*
;
import
cn.noexception.container.aop.aspectj.AspectJExpressionPointcutAdvisor
;
import
cn.noexception.container.aop.framework.ProxyFactory
;
import
cn.noexception.container.factory.BeanFactory
;
import
cn.noexception.container.factory.BeanFactoryAware
;
import
cn.noexception.container.factory.config.InstantiationAwareBeanPostProcessor
;
import
cn.noexception.container.factory.support.DefaultListableBeanFactory
;
import
org.aopalliance.aop.Advice
;
import
org.aopalliance.intercept.MethodInterceptor
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.Collection
;
/**
* DefaultAdvisorAutoProxyCreator
* <p>加入 Bean 生命周期的自动代理创建者</p>
*
* @author 吕滔
* @Date 2021/11/4 16:53
*/
public
class
DefaultAdvisorAutoProxyCreator
implements
InstantiationAwareBeanPostProcessor
,
BeanFactoryAware
{
private
DefaultListableBeanFactory
beanFactory
;
@Override
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
throws
BeansException
{
this
.
beanFactory
=
(
DefaultListableBeanFactory
)
beanFactory
;
}
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
null
;
}
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
null
;
}
@Override
public
Object
postProcessBeforeInstantiation
(
Class
<?>
beanClass
,
String
beanName
)
throws
BeansException
{
if
(
isInfrastructureClass
(
beanClass
))
return
null
;
Collection
<
AspectJExpressionPointcutAdvisor
>
advisors
=
beanFactory
.
getBeansOfType
(
AspectJExpressionPointcutAdvisor
.
class
).
values
();
for
(
AspectJExpressionPointcutAdvisor
advisor
:
advisors
)
{
ClassFilter
classFilter
=
advisor
.
getPointcut
().
getClassFilter
();
if
(!
classFilter
.
matches
(
beanClass
))
continue
;
AdvisedSupport
advisedSupport
=
new
AdvisedSupport
();
TargetSource
targetSource
=
null
;
try
{
targetSource
=
new
TargetSource
(
beanClass
.
getDeclaredConstructor
().
newInstance
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
// 设置目标对象
advisedSupport
.
setTargetSource
(
targetSource
);
// 设置拦截方法
advisedSupport
.
setMethodInterceptor
((
MethodInterceptor
)
advisor
.
getAdvice
());
// 设置匹配器
advisedSupport
.
setMethodMatcher
(
advisor
.
getPointcut
().
getMethodMatcher
());
// 设置选择使用的代理方法
advisedSupport
.
setProxyTargetClass
(
false
);
return
new
ProxyFactory
(
advisedSupport
).
getProxy
();
}
return
null
;
}
/**
* 检测/感知 bean 是否是切点 <p>按需拦截
*/
private
boolean
isInfrastructureClass
(
Class
<?>
beanClass
)
{
return
Advice
.
class
.
isAssignableFrom
(
beanClass
)
||
Pointcut
.
class
.
isAssignableFrom
(
beanClass
)
||
Advisor
.
class
.
isAssignableFrom
(
beanClass
);
}
}
src/main/java/cn/noexception/container/factory/config/InstantiationAwareBeanPostProcessor.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.container.factory.config
;
import
cn.noexception.container.BeansException
;
/**
* InstantiationAwareBeanPostProcessor
*
* @author 吕滔
* @Date 2021/11/4 16:55
*/
public
interface
InstantiationAwareBeanPostProcessor
extends
BeanPostProcessor
{
/**
* 在 Bean 对象执行初始化方法之前,执行此方法
*/
Object
postProcessBeforeInstantiation
(
Class
<?>
beanClass
,
String
beanName
)
throws
BeansException
;
}
src/test/java/cn/noexception/test/ApiRunner.java
浏览文件 @
bbce0776
...
...
@@ -71,4 +71,12 @@ public class ApiRunner {
// 测试调用
System
.
out
.
println
(
"测试结果:"
+
proxy_cglib
.
register
(
"感冒灵"
));
}
@Test
public
void
test_aop
(){
ClassPathXmlApplicationContext
applicationContext
=
new
ClassPathXmlApplicationContext
(
"classpath:config_aop.xml"
);
IUserService
userService
=
applicationContext
.
getBean
(
"userService"
,
IUserService
.
class
);
System
.
out
.
println
(
"测试结果:"
+
userService
.
queryUserInfo
());
}
}
src/test/java/cn/noexception/test/bean/UserServiceBeforeAdvice.java
0 → 100644
浏览文件 @
bbce0776
package
cn.noexception.test.bean
;
import
cn.noexception.container.aop.MethodBeforeAdvice
;
import
java.lang.reflect.Method
;
/**
* UserServiceBeforeAdvice
*
* @author 吕滔
* @Date 2021/11/4 17:30
*/
public
class
UserServiceBeforeAdvice
implements
MethodBeforeAdvice
{
@Override
public
void
before
(
Method
method
,
Object
[]
args
,
Object
target
)
throws
Throwable
{
System
.
out
.
println
(
"拦截方法:"
+
method
.
getName
());
}
}
src/test/resources/config_aop.xml
0 → 100644
浏览文件 @
bbce0776
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean
id=
"userService"
class=
"cn.noexception.test.bean.UserService"
/>
<bean
class=
"cn.noexception.container.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
/>
<bean
id=
"beforeAdvice"
class=
"cn.noexception.test.bean.UserServiceBeforeAdvice"
/>
<bean
id=
"methodInterceptor"
class=
"cn.noexception.container.aop.framework.adapter.MethodBeforeAdviceInterceptor"
>
<property
name=
"advice"
ref=
"beforeAdvice"
/>
</bean>
<bean
id=
"pointcutAdvisor"
class=
"cn.noexception.container.aop.aspectj.AspectJExpressionPointcutAdvisor"
>
<property
name=
"expression"
value=
"execution(* cn.noexception.test.bean.IUserService.*(..))"
/>
<property
name=
"advice"
ref=
"methodInterceptor"
/>
</bean>
</beans>
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录