提交 2bb37d5d 编写于 作者: 希川's avatar 希川

<feat>: 通过注解,注入属性信息

上级 853bbdd5
package cn.noexception.container.aop.framework.autoproxy;
import cn.noexception.container.BeansException;
import cn.noexception.container.PropertyValues;
import cn.noexception.container.aop.*;
import cn.noexception.container.aop.aspectj.AspectJExpressionPointcutAdvisor;
import cn.noexception.container.aop.framework.ProxyFactory;
......@@ -78,4 +79,9 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
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;
}
}
......@@ -132,4 +132,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader i
// 执行单利 bean 的销毁方法
getBeanFactory().destroySingletons();
}
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(requiredType);
}
}
......@@ -17,4 +17,6 @@ public interface BeanFactory {
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
}
......@@ -7,6 +7,7 @@ import cn.noexception.container.factory.config.BeanDefinition;
import cn.noexception.container.factory.config.BeanFactoryPostProcessor;
import cn.noexception.container.factory.io.DefaultResourceLoader;
import cn.noexception.container.factory.io.Resource;
import cn.noexception.container.factory.utils.StringValueResolver;
import java.util.Properties;
......@@ -42,19 +43,14 @@ public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
Object value = propertyValue.getValue();
if (!(value instanceof String)) continue;
String strVal = (String) value;
StringBuilder buffer = new StringBuilder(strVal);
int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) {
String propKey = strVal.substring(startIdx+2, stopIdx);
String propVal = properties.getProperty(propKey);
buffer.replace(startIdx, stopIdx+1, propVal);
propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), buffer.toString()));
}
value = resolvePlaceholder((String) value, properties);
propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), value));
}
}
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties);
beanFactory.addEmbeddedValueResolver(valueResolver);
}catch (Exception ex){
throw new BeansException(" properties 加载失败", ex);
}
......@@ -63,4 +59,32 @@ public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
public void setLocation(String location) {
this.location = location;
}
private class PlaceholderResolvingStringValueResolver implements StringValueResolver{
private final Properties properties;
private PlaceholderResolvingStringValueResolver(Properties properties) {
this.properties = properties;
}
@Override
public String resolveStringValue(String strVal) {
return PropertyPlaceholderConfigurer.this.resolvePlaceholder(strVal, properties);
}
}
private String resolvePlaceholder(String strVal, Properties properties) {
StringBuilder buffer = new StringBuilder(strVal);
int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) {
String propKey = strVal.substring(startIdx + 2, stopIdx);
String propVal = properties.getProperty(propKey);
buffer.replace(startIdx, stopIdx + 1, propVal);
}
return buffer.toString();
}
}
package cn.noexception.container.factory.annotation;
import cn.hutool.core.bean.BeanUtil;
import cn.noexception.container.BeansException;
import cn.noexception.container.PropertyValues;
import cn.noexception.container.factory.BeanFactory;
import cn.noexception.container.factory.BeanFactoryAware;
import cn.noexception.container.factory.ConfigurableListableBeanFactory;
import cn.noexception.container.factory.config.InstantiationAwareBeanPostProcessor;
import cn.noexception.container.factory.utils.ClassUtils;
import java.lang.reflect.Field;
/**
* AutowiredAnnotationBeanPostProcessor
* 扫描自定义注解
*
* @author 吕滔
* @Date 2021/11/9 11:08
*/
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
private ConfigurableListableBeanFactory 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 {
return null;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
// 1. 处理注解 @InputValue
Class<?> clazz = bean.getClass();
clazz = ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
InputValue valueAnnotation = field.getAnnotation(InputValue.class);
if (null != valueAnnotation) {
// 将注解中的占位符表达式转换成值
String value = valueAnnotation.value();
value = beanFactory.resolveEmbeddedValue(value);
BeanUtil.setFieldValue(bean, field.getName(), value);
}
}
// 2. 处理注解 @Inject
for (Field field : declaredFields) {
Inject injectAnnotation = field.getAnnotation(Inject.class);
if (null != injectAnnotation) {
Class<?> fieldType = field.getType();
String dependentBeanName = null;
Priority priorityAnnotation = field.getAnnotation(Priority.class);
Object dependentBean = null;
if (null != priorityAnnotation) {
dependentBeanName = priorityAnnotation.value();
dependentBean = beanFactory.getBean(dependentBeanName, fieldType);
} else {
dependentBean = beanFactory.getBean(fieldType);
}
BeanUtil.setFieldValue(bean, field.getName(), dependentBean);
}
}
return pvs;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}
package cn.noexception.container.factory.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Inject
*
* @author 吕滔
* @Date 2021/11/9 10:59
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
public @interface Inject {
}
package cn.noexception.container.factory.annotation;
import java.lang.annotation.*;
/**
* InputValue
*
* @author 吕滔
* @Date 2021/11/9 11:03
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InputValue {
String value();
}
package cn.noexception.container.factory.annotation;
import java.lang.annotation.*;
/**
* Priority
*
* @author 吕滔
* @Date 2021/11/9 11:01
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Priority {
String value() default "";
}
package cn.noexception.container.factory.config;
import cn.noexception.container.factory.HierarchicalBeanFactory;
import cn.noexception.container.factory.utils.StringValueResolver;
/**
* ConfigurableBeanFactory
......@@ -18,4 +19,8 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* 销毁单例对象
*/
void destroySingletons();
void addEmbeddedValueResolver(StringValueResolver valueResolver);
String resolveEmbeddedValue(String value);
}
package cn.noexception.container.factory.config;
import cn.noexception.container.BeansException;
import cn.noexception.container.PropertyValues;
/**
* InstantiationAwareBeanPostProcessor
......@@ -13,4 +14,14 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* 在 Bean 对象执行初始化方法之前,执行此方法
*/
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
/**
* 在 Bean 对象实例化完成后,设置属性操作之前执行此方法
* @param pvs
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException;
}
......@@ -32,6 +32,8 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
}
// 实例化 Bean
bean = createBeanInstance(beanDefinition, beanName, args);
// 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值
applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition);
// 给 Bean 填充属性值
applyPropertyValues(beanName, bean, beanDefinition);
// 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法
......@@ -49,6 +51,29 @@ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFa
return bean;
}
/**
* 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值
*
* @param beanName
* @param bean
* @param beanDefinition
*/
protected void applyBeanPostProcessorsBeforeApplyingPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) {
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
PropertyValues pvs = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessPropertyValues(beanDefinition.getPropertyValues(), bean, beanName);
if (null != pvs) {
for (PropertyValue propertyValue : pvs.getPropertyValues()) {
beanDefinition.getPropertyValues().addPropertyValue(propertyValue);
}
}
}
}
}
protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
if (null != bean) {
......
......@@ -7,6 +7,7 @@ import cn.noexception.container.factory.config.BeanDefinition;
import cn.noexception.container.factory.config.BeanPostProcessor;
import cn.noexception.container.factory.config.ConfigurableBeanFactory;
import cn.noexception.container.factory.utils.ClassUtils;
import cn.noexception.container.factory.utils.StringValueResolver;
import java.util.ArrayList;
import java.util.List;
......@@ -22,6 +23,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
/**
* String resolvers to apply e.g. to annotation attribute values
*/
private final List<StringValueResolver> embeddedValueResolvers = new ArrayList<>();
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null);
......@@ -77,4 +83,18 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
public ClassLoader getBeanClassLoader() {
return beanClassLoader;
}
@Override
public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
this.embeddedValueResolvers.add(valueResolver);
}
@Override
public String resolveEmbeddedValue(String value) {
String result = value;
for (StringValueResolver resolver : this.embeddedValueResolvers) {
result = resolver.resolveStringValue(result);
}
return result;
}
}
......@@ -4,7 +4,9 @@ import cn.noexception.container.BeansException;
import cn.noexception.container.factory.ConfigurableListableBeanFactory;
import cn.noexception.container.factory.config.BeanDefinition;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
......@@ -56,4 +58,20 @@ public class DefaultListableBeanFactory extends AbstractAutowiredCapableBeanFact
public void preInstantiateSingletons() throws BeansException {
beanDefinitionMap.keySet().forEach(this::getBean);
}
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
List<String> beanNames = new ArrayList<>();
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
Class beanClass = entry.getValue().getBeanClass();
if (requiredType.isAssignableFrom(beanClass)) {
beanNames.add(entry.getKey());
}
}
if (1 == beanNames.size()) {
return getBean(beanNames.get(0), requiredType);
}
throw new BeansException(requiredType + "expected single bean but found " + beanNames.size() + ": " + beanNames);
}
}
package cn.noexception.container.factory.utils;
/**
* StringValueResolver
* <p>
* 解析字符串接口
*
* @author 吕滔
* @Date 2021/11/9 10:37
*/
public interface StringValueResolver {
String resolveStringValue(String strVal);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册