Во-первых, я не уверен, стоит ли делать все это.
Цель состоит в том, чтобы создать несколько интерфейсов с аннотациями, чтобы скрыть устаревший доступ к строкам на основе позиции из базы данных конфигурации, без реализации каждого интерфейса. .
Декларативно настроенный интерфейс:
public interface LegacyConfigItem extends ConfigDbAccess{
@Subfield(length=3)
String BWHG();
@Subfield(start = 3, length=1)
int BNKST();
@Subfield(start = 4, length=1)
int BEINH();
:
}
Базовый интерфейс для идентификации во время выполнения
public interface ConfigDbAccess{
}
Пустая реализация без функциональности, может измениться.
public class EmptyImpl {
}
Перехватчик Beanfactory и MethodInvocation, для обработки нереализованных методов.
@Component
public class InterfaceBeanFactory extends DefaultListableBeanFactory {
protected static final int TEXT_MAX = 400;
@Autowired
private EntityRepo entityRepo;
public <T> T getInstance(Class<T> legacyInterface, String key) {
ProxyFactory factory = new ProxyFactory(new EmptyImpl());
factory.setInterfaces(legacyInterface);
factory.setExposeProxy(true);
factory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
KEY keyAnnotation = invocation.getThis().getClass().getAnnotation(Key.class);
String key= keyAnnotation.key().toUpperCase();
String ptart = invocation.getMethod().getDeclaringClass().getSimpleName();
Vpt result = entityRepo.getOne(new EntityId(ptart.toUpperCase(), schl.toUpperCase()));
Subfield sub = invocation.getMethod().getAnnotation(Subfield.class);
//TODO: Raise missing Subfield annotation
int start = sub.start();
int length = sub.length();
if (start + length > TEXT_MAX) {
//TODO: Raise invalid Subfield config
}
String value = result.getTextField().substring(start,start+length);
return value;
}
});
return (T) factory.getProxy();
}
@Override
protected Map<String, Object> findAutowireCandidates(String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
Map<String, Object> map = super.findAutowireCandidates(beanName, requiredType, descriptor);
if (ConfigDbAccess.class.isAssignableFrom(requiredType )) {
:
@SpringBootApplication
public class JpaDemoApplication {
@Autowired
private ApplicationContext context;
public static void main(String[] args) {
SpringApplication app = new SpringApplication(JpaDemoApplication.class);
// app.setApplicationContextClass(InterfaceInjectionContext .class);
app.run(args);
}
public class InterfaceInjectionContext extends AnnotationConfigApplicationContext {
public VptInjectionContext () {
super (new InterfaceBeanFactory ());
}
}
Пока все это работает, за исключением случаев, когда я пытаюсь установить класс приложения для класса DefaultListableBeanFactory,Я убиваю стартовую сеть Spring. Приложение запускается, внедряет поля Autowired с моей перехваченной псевдо-реализацией - и заканчивается.
Я думаю, что я делаю что-то не так с регистрацией DefaultListableBeanFactory, но я понятия не имею, как это сделать правильно.