Skip to content
Merged

Dev #430

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion aop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>run.soeasy.framework</groupId>
<artifactId>framework</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<artifactId>aop</artifactId>
<name>aop</name>
Expand Down
20 changes: 10 additions & 10 deletions aop/src/main/java/run/soeasy/framework/aop/Aop.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import run.soeasy.framework.core.RandomUtils;
import run.soeasy.framework.core.StringUtils;
import run.soeasy.framework.core.collection.ArrayUtils;
import run.soeasy.framework.core.collection.Elements;
import run.soeasy.framework.core.execute.Execution;
import run.soeasy.framework.core.streaming.Streamable;

/**
* AOP核心组件,继承自{@link JdkProxyFactory},提供基于JDK动态代理的AOP功能实现,
Expand Down Expand Up @@ -119,12 +119,12 @@ public Proxy getProxy(@NonNull Class<?> sourceClass, Class<?>[] interfaces,
this.id);

// 合并拦截器:标识拦截器 + 全局注册拦截器 + 自定义拦截器
Elements<? extends ExecutionInterceptor> executionInterceptors;
Streamable<? extends ExecutionInterceptor> executionInterceptors;
if (executionInterceptor == null) {
executionInterceptors = Elements.forArray(delegatedObjectExecutionInterceptor,
executionInterceptors = Streamable.array(delegatedObjectExecutionInterceptor,
getExecutionInterceptorRegistry());
} else {
executionInterceptors = Elements.forArray(delegatedObjectExecutionInterceptor,
executionInterceptors = Streamable.array(delegatedObjectExecutionInterceptor,
getExecutionInterceptorRegistry(), executionInterceptor);
}

Expand Down Expand Up @@ -177,12 +177,12 @@ public Execution getProxyFunction(@NonNull Execution execution, ExecutionInterce
this.id);

// 合并拦截器
Elements<? extends ExecutionInterceptor> executionInterceptors;
Streamable<? extends ExecutionInterceptor> executionInterceptors;
if (executionInterceptor == null) {
executionInterceptors = Elements.forArray(delegatedObjectExecutionInterceptor,
executionInterceptors = Streamable.array(delegatedObjectExecutionInterceptor,
getExecutionInterceptorRegistry());
} else {
executionInterceptors = Elements.forArray(delegatedObjectExecutionInterceptor,
executionInterceptors = Streamable.array(delegatedObjectExecutionInterceptor,
getExecutionInterceptorRegistry(), executionInterceptor);
}

Expand Down Expand Up @@ -225,11 +225,11 @@ public <T> Proxy getProxy(@NonNull Class<? extends T> sourceClass, T source, Cla
source);

// 合并拦截器:切换目标拦截器 + 自定义拦截器
Elements<? extends ExecutionInterceptor> executionInterceptors;
Streamable<? extends ExecutionInterceptor> executionInterceptors;
if (executionInterceptor == null) {
executionInterceptors = Elements.forArray(switchableTargetExecutionInterceptor);
executionInterceptors = Streamable.array(switchableTargetExecutionInterceptor);
} else {
executionInterceptors = Elements.forArray(switchableTargetExecutionInterceptor, executionInterceptor);
executionInterceptors = Streamable.array(switchableTargetExecutionInterceptor, executionInterceptor);
}

// 包装为拦截器集合并创建代理
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class DelegatedObjectExecutionInterceptor implements InvocationInterceptor, Seri
@Override
public Object intercept(@NonNull Invocation executor) throws Throwable {
// 判断是否为获取代理容器ID的方法调用(方法名匹配且无参数)
if (executor.getMetadata().getParameterTemplate().isEmpty()
if (executor.getMetadata().getParameterMapping().isEmpty()
&& executor.getMetadata().getName().equals(DelegatedObject.PROXY_CONTAINER_ID_METHOD_NAME)) {
return id; // 返回预设的代理容器ID
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.NonNull;
import run.soeasy.framework.core.execute.Execution;
import run.soeasy.framework.core.spi.ConfigurableServices;
import run.soeasy.framework.core.spi.ServiceComparator;

/**
* 执行拦截器注册中心,继承自{@link ConfigurableServices}并实现{@link ExecutionInterceptor}接口,
Expand Down Expand Up @@ -30,7 +31,7 @@ public class ExecutionInterceptorRegistry extends ConfigurableServices<Execution
* 构造执行拦截器注册中心,指定服务类为{@link ExecutionInterceptor}
*/
public ExecutionInterceptorRegistry() {
setServiceClass(ExecutionInterceptor.class);
super(ServiceComparator.defaultServiceComparator());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

import lombok.Data;
import lombok.NonNull;
import run.soeasy.framework.core.collection.Elements;
import run.soeasy.framework.core.execute.Execution;
import run.soeasy.framework.core.streaming.Streamable;

/**
* 执行拦截器集合,实现{@link ExecutionInterceptor}接口,用于管理一组组拦截器并形成拦截链,
* 将多个拦截器按顺序执行,简化多拦截器场景的配置与调用,是AOP框架中批量管理拦截器的工具类。
*
* <p>该类持有一个拦截器元素集合({@link Elements}),在拦截执行时,通过创建{@link ExecutionInterceptorChain}
* <p>该类持有一个拦截器元素集合({@link Streamable}),在拦截执行时,通过创建{@link ExecutionInterceptorChain}
* 将拦截器集合转换为拦截链,按迭代顺序依次执行每个拦截器,最终触发{@code nextChain}(目标执行逻辑),
* 实现多拦截器的有序增强。
*
* @author soeasy.run
* @see ExecutionInterceptor
* @see ExecutionInterceptorChain
* @see Elements
* @see Streamable
*/
@Data
public class ExecutionInterceptors implements ExecutionInterceptor {
Expand All @@ -25,7 +25,7 @@ public class ExecutionInterceptors implements ExecutionInterceptor {
* 拦截器元素集合(非空),包含需要按序执行的拦截器
*/
@NonNull
private final Elements<? extends ExecutionInterceptor> executionInterceptors;
private final Streamable<? extends ExecutionInterceptor> executionInterceptors;

/**
* 拦截链执行完毕后触发的下一个执行节点(通常为目标业务逻辑)
Expand All @@ -47,7 +47,7 @@ public class ExecutionInterceptors implements ExecutionInterceptor {
@Override
public Object intercept(@NonNull Execution function) throws Throwable {
// 创建拦截器链,关联当前拦截器集合与下一个执行节点
ExecutionInterceptorChain chain = new ExecutionInterceptorChain(executionInterceptors.iterator(), nextChain);
ExecutionInterceptorChain chain = new ExecutionInterceptorChain(executionInterceptors.toList().iterator(), nextChain);
// 执行拦截链
return chain.intercept(function);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.NonNull;
import run.soeasy.framework.core.spi.ConfigurableServices;
import run.soeasy.framework.core.spi.ServiceComparator;
import run.soeasy.framework.core.type.ClassUtils;

/**
Expand All @@ -23,7 +24,7 @@ public class ProxyFactories extends ConfigurableServices<ProxyFactory> implement
* 构造代理工厂集合,指定服务类为{@link ProxyFactory}
*/
public ProxyFactories() {
setServiceClass(ProxyFactory.class);
super(ServiceComparator.defaultServiceComparator());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion beans/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>run.soeasy.framework</groupId>
<artifactId>framework</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</parent>
<artifactId>beans</artifactId>
<name>beans</name>
Expand Down
11 changes: 1 addition & 10 deletions beans/src/main/java/run/soeasy/framework/beans/BeanFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import lombok.Setter;
import run.soeasy.framework.codec.Codec;
import run.soeasy.framework.codec.format.KeyValueFormat;
import run.soeasy.framework.core.convert.value.TypedValueAccessor;
import run.soeasy.framework.core.domain.KeyValue;
import run.soeasy.framework.core.transform.property.TypedProperties;
import run.soeasy.framework.core.transform.templates.Mapping;

/**
* 基于JavaBean的键值格式化器,继承自{@link KeyValueFormat},专门用于将JavaBean对象与键值对格式(如查询字符串、表单数据)进行互转,
Expand Down Expand Up @@ -46,13 +43,7 @@ public BeanFormat(@NonNull CharSequence delimiter, @NonNull CharSequence connect
// 注册Object类型的映射器:将任意Bean转换为键值对流
getKeyValueMapper().getMappingProvider().register(Object.class, (bean, type) -> {
// 通过BeanMapper获取Bean的类型化属性集合
TypedProperties typedProperties = BeanUtils.getProperties(bean, type);

// 定义Bean到键值对流的映射逻辑
Mapping<Object, TypedValueAccessor> mapping = () -> typedProperties.getElements()
.map(property -> KeyValue.of(property.getKey(), property.getValue()));

return mapping;
return BeanUtils.getProperties(bean, type);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
import java.beans.IntrospectionException;

import lombok.NonNull;
import run.soeasy.framework.core.transform.property.ObjectTemplateFactory;
import run.soeasy.framework.core.transform.property.PropertyTemplate;
import run.soeasy.framework.core.mapping.property.ObjectTemplateFactory;
import run.soeasy.framework.core.mapping.property.PropertyMapping;

/**
* Bean信息工厂接口,继承自{@link ObjectTemplateFactory},定义获取JavaBean信息({@link BeanInfo})和创建Bean属性模板的规范,
* 作为JavaBean内省机制的抽象,提供Bean信息的统一获取方式,适配不同的Bean信息解析策略。
*
* <p>
* 该接口结合内省机制,既可以直接获取{@link BeanInfo}用于自定义处理,也可以通过默认方法创建{@link BeanPropertyTemplate},
* 该接口结合内省机制,既可以直接获取{@link BeanInfo}用于自定义处理,也可以通过默认方法创建{@link BeanInfoMapping},
* 简化Bean属性元数据的访问与管理流程。
*
* @author soeasy.run
* @see ObjectTemplateFactory
* @see BeanInfo
* @see BeanPropertyTemplate
* @see BeanInfoMapping
*/
public interface BeanInfoFactory extends ObjectTemplateFactory<BeanProperty> {

Expand All @@ -27,7 +27,7 @@ public interface BeanInfoFactory extends ObjectTemplateFactory<BeanProperty> {
*
* <p>
* 通过内省机制解析Bean类,获取包含属性、方法、事件等信息的{@link BeanInfo}对象,
* 是后续创建{@link BeanProperty}和{@link BeanPropertyTemplate}的基础。
* 是后续创建{@link BeanProperty}和{@link BeanInfoMapping}的基础。
*
* @param beanClass 目标Bean类(非空)
* @return 包含Bean元信息的{@link BeanInfo}对象
Expand All @@ -39,14 +39,14 @@ public interface BeanInfoFactory extends ObjectTemplateFactory<BeanProperty> {
* 创建指定Bean类的属性模板(默认实现)
*
* <p>
* 基于当前{@link BeanInfoFactory}实例和目标Bean类,创建{@link BeanPropertyTemplate},
* 基于当前{@link BeanInfoFactory}实例和目标Bean类,创建{@link BeanInfoMapping},
* 实现{@link ObjectTemplateFactory}接口的规范方法,提供Bean属性模板的默认创建逻辑。
*
* @param objectClass 目标Bean类(即JavaBean的类对象)
* @return 针对该Bean类的{@link BeanPropertyTemplate}实例
* @return 针对该Bean类的{@link BeanInfoMapping}实例
*/
@Override
default PropertyTemplate<BeanProperty> getObjectTemplate(Class<?> objectClass) {
return new BeanPropertyTemplate(objectClass, this);
default PropertyMapping<BeanProperty> getObjectTemplate(Class<?> objectClass) {
return new BeanInfoMapping(objectClass, this).standard();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package run.soeasy.framework.beans;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.util.stream.Stream;

import lombok.NonNull;
import run.soeasy.framework.core.mapping.property.PropertyMapping;
import run.soeasy.framework.core.mapping.property.StreamablePropertyMapping;
import run.soeasy.framework.core.streaming.Streamable;
import run.soeasy.framework.core.type.ReflectionUtils;

public class BeanInfoMapping extends StreamablePropertyMapping<BeanProperty> {

public BeanInfoMapping(@NonNull Streamable<BeanProperty> elements) {
super(elements);
}

public BeanInfoMapping(@NonNull Class<?> beanClass, @NonNull BeanInfo beanInfo) {
this(Streamable.array(beanInfo.getPropertyDescriptors())
.map((descriptor) -> new BeanProperty(beanClass, descriptor)));
}

protected BeanInfoMapping(@NonNull Class<?> beanClass, @NonNull BeanInfoFactory beanInfoFactory) {
this(Streamable.of(() -> {
BeanInfo beanInfo;
try {
beanInfo = beanInfoFactory.getBeanInfo(beanClass);
} catch (IntrospectionException e) {
throw new FatalBeanException("Failed to obtain BeanInfo for class [" + beanClass + "]", e);
}
// 将属性描述符转换为BeanProperty,并过滤忽略的属性
return Stream.of(beanInfo.getPropertyDescriptors())
.map((descriptor) -> new BeanProperty(beanClass, descriptor)).iterator();
}));
}

public PropertyMapping<BeanProperty> standard() {
return new BeanInfoMapping(this.elements().filter((property) -> {
return property.getReadMethod() != null && property.getReadMethod().getSource() != null
&& !ReflectionUtils.isObjectMethod(property.getReadMethod().getSource());
})).toMultiMapped();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package run.soeasy.framework.beans;

import lombok.Getter;
import run.soeasy.framework.core.transform.property.PropertyMapper;
import run.soeasy.framework.core.mapping.property.PropertyMapper;

/**
* Bean映射工具类,继承自{@link PropertyMapper},专门用于处理JavaBean之间的属性复制与转换,
Expand Down

This file was deleted.

Loading
Loading