Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
希川
container-mini
提交
0b2c279b
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,发现更多精彩内容 >>
提交
0b2c279b
编写于
11月 17, 2021
作者:
希川
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
<feat>: 循环依赖问题 part two
上级
f30bb862
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
237 addition
and
31 deletion
+237
-31
src/main/java/cn/noexception/container/aop/framework/adapter/MethodBeforeAdviceInterceptor.java
.../aop/framework/adapter/MethodBeforeAdviceInterceptor.java
+8
-0
src/main/java/cn/noexception/container/aop/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
...p/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
+44
-23
src/main/java/cn/noexception/container/factory/config/InstantiationAwareBeanPostProcessor.java
...r/factory/config/InstantiationAwareBeanPostProcessor.java
+4
-0
src/main/java/cn/noexception/container/factory/support/AbstractAutowiredCapableBeanFactory.java
.../factory/support/AbstractAutowiredCapableBeanFactory.java
+24
-7
src/main/java/cn/noexception/container/factory/support/DefaultSingletonBeanRegistry.java
...ntainer/factory/support/DefaultSingletonBeanRegistry.java
+1
-1
src/test/java/cn/noexception/test/ApiRunner.java
src/test/java/cn/noexception/test/ApiRunner.java
+11
-0
src/test/java/cn/noexception/test/loop/Husband.java
src/test/java/cn/noexception/test/loop/Husband.java
+23
-0
src/test/java/cn/noexception/test/loop/HusbandMother.java
src/test/java/cn/noexception/test/loop/HusbandMother.java
+28
-0
src/test/java/cn/noexception/test/loop/IMother.java
src/test/java/cn/noexception/test/loop/IMother.java
+11
-0
src/test/java/cn/noexception/test/loop/SpouseAdvice.java
src/test/java/cn/noexception/test/loop/SpouseAdvice.java
+18
-0
src/test/java/cn/noexception/test/loop/Wife.java
src/test/java/cn/noexception/test/loop/Wife.java
+32
-0
src/test/resources/spring-loop.xml
src/test/resources/spring-loop.xml
+33
-0
未找到文件。
src/main/java/cn/noexception/container/aop/framework/adapter/MethodBeforeAdviceInterceptor.java
浏览文件 @
0b2c279b
...
@@ -30,4 +30,12 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor {
...
@@ -30,4 +30,12 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor {
this
.
advice
.
before
(
invocation
.
getMethod
(),
invocation
.
getArguments
(),
invocation
.
getThis
());
this
.
advice
.
before
(
invocation
.
getMethod
(),
invocation
.
getArguments
(),
invocation
.
getThis
());
return
invocation
.
proceed
();
return
invocation
.
proceed
();
}
}
public
MethodBeforeAdvice
getAdvice
()
{
return
advice
;
}
public
void
setAdvice
(
MethodBeforeAdvice
advice
)
{
this
.
advice
=
advice
;
}
}
}
src/main/java/cn/noexception/container/aop/framework/autoproxy/DefaultAdvisorAutoProxyCreator.java
浏览文件 @
0b2c279b
...
@@ -14,6 +14,9 @@ import org.aopalliance.intercept.MethodInterceptor;
...
@@ -14,6 +14,9 @@ import org.aopalliance.intercept.MethodInterceptor;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.Collection
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.Set
;
/**
/**
* DefaultAdvisorAutoProxyCreator
* DefaultAdvisorAutoProxyCreator
...
@@ -26,6 +29,8 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
...
@@ -26,6 +29,8 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
private
DefaultListableBeanFactory
beanFactory
;
private
DefaultListableBeanFactory
beanFactory
;
private
final
Set
<
Object
>
earlyProxyReferences
=
Collections
.
synchronizedSet
(
new
HashSet
<>());
@Override
@Override
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
throws
BeansException
{
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
throws
BeansException
{
this
.
beanFactory
=
(
DefaultListableBeanFactory
)
beanFactory
;
this
.
beanFactory
=
(
DefaultListableBeanFactory
)
beanFactory
;
...
@@ -38,10 +43,45 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
...
@@ -38,10 +43,45 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
@Override
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
if
(
isInfrastructureClass
(
bean
.
getClass
()))
return
bean
;
if
(!
earlyProxyReferences
.
contains
(
beanName
))
{
return
wrapIfNecessary
(
bean
,
beanName
);
}
return
bean
;
}
Collection
<
AspectJExpressionPointcutAdvisor
>
advisors
=
beanFactory
.
getBeansOfType
(
AspectJExpressionPointcutAdvisor
.
class
).
values
();
@Override
public
Object
postProcessBeforeInstantiation
(
Class
<?>
beanClass
,
String
beanName
)
throws
BeansException
{
return
null
;
}
@Override
public
boolean
postProcessAfterInstantiation
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
true
;
}
/**
* 检测/感知 bean 是否是切点 <p>按需拦截
*/
private
boolean
isInfrastructureClass
(
Class
<?>
beanClass
)
{
return
Advice
.
class
.
isAssignableFrom
(
beanClass
)
||
Pointcut
.
class
.
isAssignableFrom
(
beanClass
)
||
Advisor
.
class
.
isAssignableFrom
(
beanClass
);
}
@Override
public
PropertyValues
postProcessPropertyValues
(
PropertyValues
pvs
,
Object
bean
,
String
beanName
)
throws
BeansException
{
return
pvs
;
}
@Override
public
Object
getEarlyBeanReference
(
Object
exposedObject
,
String
beanName
)
{
earlyProxyReferences
.
add
(
beanName
);
return
wrapIfNecessary
(
exposedObject
,
beanName
);
}
protected
Object
wrapIfNecessary
(
Object
bean
,
String
beanName
)
{
if
(
isInfrastructureClass
(
bean
.
getClass
()))
{
return
bean
;
}
Collection
<
AspectJExpressionPointcutAdvisor
>
advisors
=
beanFactory
.
getBeansOfType
(
AspectJExpressionPointcutAdvisor
.
class
).
values
();
for
(
AspectJExpressionPointcutAdvisor
advisor
:
advisors
)
{
for
(
AspectJExpressionPointcutAdvisor
advisor
:
advisors
)
{
ClassFilter
classFilter
=
advisor
.
getPointcut
().
getClassFilter
();
ClassFilter
classFilter
=
advisor
.
getPointcut
().
getClassFilter
();
// 过滤匹配类
// 过滤匹配类
...
@@ -57,34 +97,15 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
...
@@ -57,34 +97,15 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
// 设置匹配器
// 设置匹配器
advisedSupport
.
setMethodMatcher
(
advisor
.
getPointcut
().
getMethodMatcher
());
advisedSupport
.
setMethodMatcher
(
advisor
.
getPointcut
().
getMethodMatcher
());
// 设置选择使用的代理方法
// 设置选择使用的代理方法
advisedSupport
.
setProxyTargetClass
(
fals
e
);
advisedSupport
.
setProxyTargetClass
(
tru
e
);
// 返回代理对象
// 返回代理对象
return
new
ProxyFactory
(
advisedSupport
).
getProxy
();
return
new
ProxyFactory
(
advisedSupport
).
getProxy
();
}
}
return
bean
;
return
bean
;
}
}
}
@Override
public
Object
postProcessBeforeInstantiation
(
Class
<?>
beanClass
,
String
beanName
)
throws
BeansException
{
return
null
;
}
@Override
public
boolean
postProcessAfterInstantiation
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
true
;
}
/**
* 检测/感知 bean 是否是切点 <p>按需拦截
*/
private
boolean
isInfrastructureClass
(
Class
<?>
beanClass
)
{
return
Advice
.
class
.
isAssignableFrom
(
beanClass
)
||
Pointcut
.
class
.
isAssignableFrom
(
beanClass
)
||
Advisor
.
class
.
isAssignableFrom
(
beanClass
);
}
@Override
public
PropertyValues
postProcessPropertyValues
(
PropertyValues
pvs
,
Object
bean
,
String
beanName
)
throws
BeansException
{
return
pvs
;
}
}
src/main/java/cn/noexception/container/factory/config/InstantiationAwareBeanPostProcessor.java
浏览文件 @
0b2c279b
...
@@ -33,4 +33,8 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
...
@@ -33,4 +33,8 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* @throws BeansException
* @throws BeansException
*/
*/
PropertyValues
postProcessPropertyValues
(
PropertyValues
pvs
,
Object
bean
,
String
beanName
)
throws
BeansException
;
PropertyValues
postProcessPropertyValues
(
PropertyValues
pvs
,
Object
bean
,
String
beanName
)
throws
BeansException
;
default
Object
getEarlyBeanReference
(
Object
exposedObject
,
String
beanName
){
return
exposedObject
;
}
}
}
src/main/java/cn/noexception/container/factory/support/AbstractAutowiredCapableBeanFactory.java
浏览文件 @
0b2c279b
...
@@ -34,7 +34,7 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
...
@@ -34,7 +34,7 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
}
}
// 实例化后判断
// 实例化后判断
boolean
continueWithPropertyPopulation
=
applyBeanPostProcessorsAfterIn
itializ
ation
(
beanName
,
bean
);
boolean
continueWithPropertyPopulation
=
applyBeanPostProcessorsAfterIn
stanti
ation
(
beanName
,
bean
);
if
(!
continueWithPropertyPopulation
)
{
if
(!
continueWithPropertyPopulation
)
{
return
bean
;
return
bean
;
}
}
...
@@ -62,14 +62,31 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
...
@@ -62,14 +62,31 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
return
exposedObject
;
return
exposedObject
;
}
}
private
boolean
applyBeanPostProcessorsAfterInitialization
(
String
beanName
,
Object
bean
)
{
private
boolean
applyBeanPostProcessorsAfterInstantiation
(
String
beanName
,
Object
bean
)
{
// TODO
boolean
continueWithPropertyPopulation
=
true
;
return
false
;
for
(
BeanPostProcessor
beanPostProcessor
:
getBeanPostProcessors
())
{
if
(
beanPostProcessor
instanceof
InstantiationAwareBeanPostProcessor
)
{
InstantiationAwareBeanPostProcessor
instantiationAwareBeanPostProcessor
=
(
InstantiationAwareBeanPostProcessor
)
beanPostProcessor
;
if
(!
instantiationAwareBeanPostProcessor
.
postProcessAfterInstantiation
(
bean
,
beanName
))
{
continueWithPropertyPopulation
=
false
;
break
;
}
}
}
return
continueWithPropertyPopulation
;
}
}
protected
Object
getEarlyBeanReference
(
String
beanName
,
BeanDefinition
beanDefinition
,
Object
finalBean
)
{
protected
Object
getEarlyBeanReference
(
String
beanName
,
BeanDefinition
beanDefinition
,
Object
bean
)
{
// todo
Object
exposedObject
=
bean
;
return
null
;
for
(
BeanPostProcessor
beanPostProcessor
:
getBeanPostProcessors
())
{
if
(
beanPostProcessor
instanceof
InstantiationAwareBeanPostProcessor
)
{
exposedObject
=
((
InstantiationAwareBeanPostProcessor
)
beanPostProcessor
).
getEarlyBeanReference
(
exposedObject
,
beanName
);
if
(
null
==
exposedObject
)
return
exposedObject
;
}
}
return
exposedObject
;
}
}
@Override
@Override
...
...
src/main/java/cn/noexception/container/factory/support/DefaultSingletonBeanRegistry.java
浏览文件 @
0b2c279b
...
@@ -40,7 +40,7 @@ public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
...
@@ -40,7 +40,7 @@ public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
Object
singletonObject
=
singletonObjects
.
get
(
beanName
);
Object
singletonObject
=
singletonObjects
.
get
(
beanName
);
if
(
null
==
singletonObject
)
{
if
(
null
==
singletonObject
)
{
singletonObject
=
earlySingletonObjects
.
get
(
beanName
);
singletonObject
=
earlySingletonObjects
.
get
(
beanName
);
// 判断
耳机
缓存中是否有对象,这个对象就是代理对象,因为只有代理对象才会放到三级缓存中
// 判断
二级
缓存中是否有对象,这个对象就是代理对象,因为只有代理对象才会放到三级缓存中
if
(
null
==
singletonObject
)
{
if
(
null
==
singletonObject
)
{
ObjectFactory
<?>
singletonFactory
=
singletonFactories
.
get
(
beanName
);
ObjectFactory
<?>
singletonFactory
=
singletonFactories
.
get
(
beanName
);
...
...
src/test/java/cn/noexception/test/ApiRunner.java
浏览文件 @
0b2c279b
...
@@ -10,6 +10,8 @@ import cn.noexception.test.bean.IUserService;
...
@@ -10,6 +10,8 @@ import cn.noexception.test.bean.IUserService;
import
cn.noexception.test.bean.UserService
;
import
cn.noexception.test.bean.UserService
;
import
cn.noexception.test.bean.UserServiceInterceptor
;
import
cn.noexception.test.bean.UserServiceInterceptor
;
import
cn.noexception.test.event.CustomEvent
;
import
cn.noexception.test.event.CustomEvent
;
import
cn.noexception.test.loop.Husband
;
import
cn.noexception.test.loop.Wife
;
import
org.junit.Test
;
import
org.junit.Test
;
public
class
ApiRunner
{
public
class
ApiRunner
{
...
@@ -79,4 +81,13 @@ public class ApiRunner {
...
@@ -79,4 +81,13 @@ public class ApiRunner {
System
.
out
.
println
(
"测试结果:"
+
userService
.
queryUserInfo
());
System
.
out
.
println
(
"测试结果:"
+
userService
.
queryUserInfo
());
}
}
@Test
public
void
test_circular
(){
ClassPathXmlApplicationContext
applicationContext
=
new
ClassPathXmlApplicationContext
(
"classpath:spring-loop.xml"
);
Husband
husband
=
applicationContext
.
getBean
(
"husband"
,
Husband
.
class
);
Wife
wife
=
applicationContext
.
getBean
(
"wife"
,
Wife
.
class
);
System
.
out
.
println
(
husband
.
queryWife
());
System
.
out
.
println
(
wife
.
queryHusband
());
}
}
}
src/test/java/cn/noexception/test/loop/Husband.java
0 → 100644
浏览文件 @
0b2c279b
package
cn.noexception.test.loop
;
/**
* Husband
*
* @author 吕滔
* @Date 2021/11/17 15:10
*/
public
class
Husband
{
private
Wife
wife
;
public
String
queryWife
(){
return
"Husband.wife"
;
}
public
Wife
getWife
()
{
return
wife
;
}
public
void
setWife
(
Wife
wife
)
{
this
.
wife
=
wife
;
}
}
src/test/java/cn/noexception/test/loop/HusbandMother.java
0 → 100644
浏览文件 @
0b2c279b
package
cn.noexception.test.loop
;
import
cn.noexception.container.factory.FactoryBean
;
import
java.lang.reflect.Proxy
;
/**
* HusbandMother
*
* @author 吕滔
* @Date 2021/11/17 15:12
*/
public
class
HusbandMother
implements
FactoryBean
<
IMother
>
{
@Override
public
IMother
getObject
()
throws
Exception
{
return
(
IMother
)
Proxy
.
newProxyInstance
(
Thread
.
currentThread
().
getContextClassLoader
(),
new
Class
[]{
IMother
.
class
},
((
proxy
,
method
,
args
)
->
"婚后媳妇妈妈的职责被婆婆代理了!"
+
method
.
getName
()));
}
@Override
public
Class
<?>
getObjectType
()
{
return
IMother
.
class
;
}
@Override
public
boolean
isSingleton
()
{
return
true
;
}
}
src/test/java/cn/noexception/test/loop/IMother.java
0 → 100644
浏览文件 @
0b2c279b
package
cn.noexception.test.loop
;
/**
* IMother
*
* @author 吕滔
* @Date 2021/11/17 15:11
*/
public
interface
IMother
{
String
callMother
();
}
src/test/java/cn/noexception/test/loop/SpouseAdvice.java
0 → 100644
浏览文件 @
0b2c279b
package
cn.noexception.test.loop
;
import
cn.noexception.container.aop.MethodBeforeAdvice
;
import
java.lang.reflect.Method
;
/**
* SpouseAdvice
*
* @author 吕滔
* @Date 2021/11/17 15:15
*/
public
class
SpouseAdvice
implements
MethodBeforeAdvice
{
@Override
public
void
before
(
Method
method
,
Object
[]
args
,
Object
target
)
throws
Throwable
{
System
.
out
.
println
(
"关怀小两口:"
+
method
);
}
}
src/test/java/cn/noexception/test/loop/Wife.java
0 → 100644
浏览文件 @
0b2c279b
package
cn.noexception.test.loop
;
/**
* Wife
*
* @author 吕滔
* @Date 2021/11/17 15:10
*/
public
class
Wife
{
private
Husband
husband
;
private
IMother
mother
;
public
String
queryHusband
(){
return
"Wife.husband、Mother.callMother: "
+
mother
.
callMother
();
}
public
Husband
getHusband
()
{
return
husband
;
}
public
void
setHusband
(
Husband
husband
)
{
this
.
husband
=
husband
;
}
public
IMother
getMother
()
{
return
mother
;
}
public
void
setMother
(
IMother
mother
)
{
this
.
mother
=
mother
;
}
}
src/test/resources/spring-loop.xml
0 → 100644
浏览文件 @
0b2c279b
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=
"http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context"
>
<bean
id=
"husband"
class=
"cn.noexception.test.loop.Husband"
>
<property
name=
"wife"
ref=
"wife"
/>
</bean>
<bean
id=
"wife"
class=
"cn.noexception.test.loop.Wife"
>
<property
name=
"husband"
ref=
"husband"
/>
<property
name=
"mother"
ref=
"husbandMother"
/>
</bean>
<bean
id=
"husbandMother"
class=
"cn.noexception.test.loop.HusbandMother"
/>
<!--验证三级缓存-->
<bean
class=
"cn.noexception.container.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
/>
<bean
id=
"beforeAdvice"
class=
"cn.noexception.test.loop.SpouseAdvice"
/>
<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.loop.Wife.*(..))"
/>
<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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录