利用spring的parent属性+javaassist+annotation 根据interface定义生成对应的实现类
定义一个FactoryBean实现类APIFactoryBean用于父类:
<bean id="apiFactoryBean" abstract="true" />
?
主要成员变量及方法如下:
public class APIFactoryBean implements FactoryBean, InitializingBean, ApplicationContextAware {
?
?private ApplicationContext ?springContext;
?
?? ?@Resource(name = "baseDao")
?? ?private BaseDao ? ? ? ? ? ? baseDao;
?
?? ?private Class<?> ? ? ? ? ? ?target; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// interface class
?
?? ?@Override
?? ?public Object getObject() throws Exception {
?? ? ? ?try {
?? ? ? ? ? ?Class<?> clazz = JavassistIbatisHelper.generate(this.target, this.springContext);
?? ? ? ? ? ?Constructor<?>[] constructors = clazz.getConstructors();
?? ? ? ? ? ?Constructor<?> constructor = null;
?? ? ? ? ? ?for (int i = 0; i < constructors.length; i++) {
?? ? ? ? ? ? ? ?if (constructors[i].getParameterTypes().length == 2) {
?? ? ? ? ? ? ? ? ? ?constructor = constructors[i];
?? ? ? ? ? ? ? ? ? ?return constructor.newInstance(this.baseDao, this.springContext);
?? ? ? ? ? ? ? ?}
?? ? ? ? ? ?}
?? ? ? ? ? ?throw new JavassitBuildBeanException(Errors.UNKOWN.getCode(), target.getCanonicalName()
?? ? ? ? ? ? ? ? ? ?+ "APIFactoryBean Exception ");
?? ? ? ?} catch (Throwable e) {
?? ? ? ? ? ?logger.error(e.getMessage(), e);
?? ? ? ? ? ?throw new JavassitBuildBeanException(Errors.UNKOWN.getCode(), target.getCanonicalName()
?? ? ? ? ? ? ? ? ? ?+ " APIFactoryBean Throwable ", e);
?? ? ? ?}
?? ?}
?
...
}
其中:JavassistIbatisHelper的generate方法利用 javaassist根据传入的类名(即target参数)及一些其他的参数(通过annotation定义)动态的生成需要构造的类。
?
定义一个需要实现JavassitTest1API接口的类:
?
<bean id="javassitTest1API" parent="apiFactoryBean">
<property name="target" value="com.api.JavassitTest1API"/>
</bean>
JavassitTest1API接口定义如下:
public interface JavassitTest1API {
?
?@Sql(value = "sample.loadTest1")
?? ?public ResultGeneralModel<Test1> loadTest1ById(@SqlParam(name = "id") String id);
}
?
类似的可以通过继承APIFactoryBean实现构造多个类:
如:
?
<bean id="javassitTest2API" parent="apiFactoryBean">
<property name="target" value="com.api.JavassitTest2API"/>
</bean>
JavassitTest2API接口定义如下:
public interface JavassitTest2API {
?
?@Sql(value = "sample.loadTest2")
?? ?public ResultGeneralModel<Test2> loadTest2ById(@SqlParam(name = "id") String id);
}
?