How to hide service classes and prevent @Autowire?

I am creating a structure that has several default implementations for an interface.

Question: how can I hide any default implementation of the interface, so users of the framework need to use the interface DefaultService, for example, to insert using @Autowired DefaultService?

interface DefaultService {
}

@Component
@Async
@ConditionalOnNotWebApplication
public class MyService1 implements DefaultService {

}

@Component
@Async
@ConditionalOnWebApplication
public class MyService2 implements DefaultService {

}

The terms of my services ensure that in every environment there is always only one service.

+4
source share
2 answers

Like @M. Deinum commented above, making the implementation services package a private right solution. I did not know that spring still sees these classes, since usually spring requires public access for annotations.


, , @Configuration :

@Configuration
public class DefaultServiceConfiguration {
    @Bean
    @ConditionalOnNotWebApplication
    public DefaultService getDefaultService1() {
        return new MyService1();
    }

    @Bean
    @ConditionalOnWebApplication
    public DefaultService getDefaultService2() {
        return new MyService2();
    }
}

public interface DefaultService {
}

@Async
protected class MyService1 {
}

@Async
protected class MyService2 {
}

, DefaultService.

+3

.

:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

    /**
     * Created by pyaswan on 8/18/17.
     */
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotAutowiredBean {

    }

BeanFactoryPostProcessor:

import com.yaswanth.NotAutowiredBean;
import java.lang.reflect.Field;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * Created by pyaswan on 8/18/17.o
 */
@Component
public class NotAutowiredBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
        throws BeansException {
        try {
            String[] illegalAutowiredBeans = beanFactory
                .getBeanNamesForAnnotation(NotAutowiredBean.class);

            String[] allBeans = beanFactory.getBeanDefinitionNames();

            for (String beanName : allBeans) {
                String beanClassName = beanFactory.getBeanDefinition(beanName).getBeanClassName();

                if (beanClassName != null) {
                    Class<?> clazz = Class.forName(beanClassName);
                    Field[] fields = clazz.getDeclaredFields();

                    for (Field field : fields) {
                        if (field.isAnnotationPresent(Autowired.class)) {
                            if (field.getType().isAnnotationPresent(NotAutowiredBean.class)) {
                                throw new BeanCreationNotAllowedException(beanName, "");
                            }
                        }
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Spring beans:

interface DefaultService {
}

@NotAutowiredBean
@Component
@Async
@ConditionalOnNotWebApplication
public class MyService1 implements DefaultService {

}

@NotAutowiredBean
@Component
@Async
@ConditionalOnWebApplication
public class MyService2 implements DefaultService {

}

@NotAutowiredBean. NotAutowiredBeanFactoryPostProcessor beans, , Autowired bean. NotAutowiredBean . , BeanCreationNotAllowedException, - .

0

Source: https://habr.com/ru/post/1683962/


All Articles