@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface ConfigurationProperties {
String prefix() default "";
String localtion() default "";
}
/**
初始化配置文件
*/
public class PropertiesPlugin implements IPlugin{
private Prop prop = null;
private ApplicationContext applicationContext;
PropertiesPlugin(ApplicationContext applicationContext){
this.applicationContext = applicationContext;
}
@SuppressWarnings({ "rawtypes","unchecked" })
@Override
public boolean start() {
List<Class> cla = ClassScanner.scanClassByAnnotation(ConfigurationProperties.class, false);
for(Class c : cla){
try {
ConfigurationProperties configurationProperties = (ConfigurationProperties) c.getAnnotation(ConfigurationProperties.class);
initProperties(configurationProperties);
Object object = applicationContext.getBean(StrKit.toLowerCaseFirst(c.getSimpleName()));
Method[] methods = c.getMethods();
for(Method method : methods){
if(method.getName().startsWith("set")){
String key = StrKit.toLowerCaseFirst(method.getName().substring(3));
method.invoke(object, convert(method.getParameterTypes()[0], prop.get(key)));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
/**
* @param configurationProperties
*
*/
private void initProperties(ConfigurationProperties configurationProperties) {
if(StrKit.isEmpoty(configurationProperties.prefix())){
prop = PropKit.use("config.properties");
}else{
prop = PropKit.use(configurationProperties.prefix());
}
}
/**
* 数据转化
* @param type
* @param s
* @return
*/
private static final Object convert(Class<?> type, String s) {
if (type == String.class) {
return s;
}
// mysql type: int, integer, tinyint(n) n > 1, smallint, mediumint
if (type == Integer.class || type == int.class) {
return Integer.parseInt(s);
}
// mysql type: bigint
if (type == Long.class || type == long.class) {
return Long.parseLong(s);
}
// mysql type: real, double
if (type == Double.class || type == double.class) {
return Double.parseDouble(s);
}
// mysql type: float
if (type == Float.class || type == float.class) {
return Float.parseFloat(s);
}
// mysql type: bit, tinyint(1)
if (type == Boolean.class || type == boolean.class) {
String value = s.toLowerCase();
if ("1".equals(value) || "true".equals(value)) {
return Boolean.TRUE;
} else if ("0".equals(value) || "false".equals(value)) {
return Boolean.FALSE;
} else {
throw new RuntimeException("Can not parse to boolean type of value: " + s);
}
}
// mysql type: decimal, numeric
if (type == java.math.BigDecimal.class) {
return new java.math.BigDecimal(s);
}
// mysql type: unsigned bigint
if (type == java.math.BigInteger.class) {
return new java.math.BigInteger(s);
}
// mysql type: binary, varbinary, tinyblob, blob, mediumblob, longblob. I have not finished the test.
if (type == byte[].class) {
return s.getBytes();
}
throw new RuntimeException(type.getName() + " can not be converted, please use other type in your config class!");
}
@Override
public boolean stop() {
return true;
}
}
//配置拦截器
public class AopInterceptor implements Interceptor{
private ApplicationContext ctx;
public AopInterceptor(ApplicationContext ctx){
this.ctx = ctx;
}
public AopInterceptor(){}
@Override
public void intercept(Invocation inv) {
Controller controller = inv.getController();
Field[] fields = controller.getClass().getDeclaredFields();
//controller层aop的自动注入
for (Field field : fields) {
Object bean = null;
if (field.isAnnotationPresent(AopBean.class)){
bean = AopManger.beanMap.get(field.getName());
initServiceBean(bean,field);
}else if(field.isAnnotationPresent(Autowired.class)){
bean = ctx.getBean(field.getName());
initServiceBean(bean,field);
}else{
continue ;
}
try {
if (bean != null) {
field.setAccessible(true);
field.set(controller, bean);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
inv.invoke();
}
private void initServiceBean(Object bean,Field field){
Class<?> cla = field.getType();
//service层aop的自动注入
for(Field f : cla.getDeclaredFields()){
Object serviceBean = null;
if(f.isAnnotationPresent(AopBean.class)){
serviceBean = AopManger.beanMap.get(f.getName());
}else if(f.isAnnotationPresent(Autowired.class)){
serviceBean = ctx.getBean(f.getName());
}
if(serviceBean != null){
try {
f.setAccessible(true);
f.set(bean, serviceBean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new NullPointerException("Field can not be null");
}
}
}
}
}
//使用方式如下
@ConfigurationProperties(prefix="girl.properties")
@Component
public class Girl {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
gir.properties配置文件如下:
name=jack
age=18
public class LoginController extends BaseController{
@Autowired
private Girl girl;
public void index(){
System.err.println(girl.getAge());
}
}
注:目前此功能不太完善,后面会进一步改善