Может ли @Autowired по типу создать определение компонента?

Когда вы используете @Autowired в Spring @Component, Spring определяет кандидатов на автоматическое подключение для каждого экземпляра компонента, что действительно не очень хорошо, когда вы используете веб-материал с областью действия @Request/@Session. Почему бы Spring просто не создать определение bean-компонента в ApplicationContext один раз и не использовать его повторно? Есть ли способ заставить это сделать?


person krosenvold    schedule 22.03.2011    source источник


Ответы (5)


AutowiredAnnotationBeanPostProcessor - это BeanPostProcessor, а не BeanFactoryPostProcessor, поэтому он не может редактировать определения Bean по замыслу. Реализация этого по-другому нарушила бы ожидаемую функциональность:

public class MyBean{

    @Autowired(required=false)
    public void setOtherBean(OtherBean o){this.otherBean=o;}
    private OtherBean otherBean;

}

Если экземпляр OtherBean недоступен, ни один из них не будет подключен, но как только он станет доступным (и я могу легко подключить его программно), следующий экземпляр MyBean (если область действия не является одноэлементной) получит новый экземпляр OtherBean (который был недоступен). до).

Я не говорю, что это вариант использования, с которым я сталкивался раньше, но это допустимый вариант использования, и он сломался бы, если бы все работало так, как вы предлагаете.

person Sean Patrick Floyd    schedule 22.03.2011
comment
Хотя мне не нравится дизайн или вариант использования, который вы описываете, он отвечает на мой вопрос;) - person krosenvold; 23.03.2011
comment
@krosenvoid Мне это тоже не нравится, но все еще в силе :-) - person Sean Patrick Floyd; 23.03.2011

Да: Spring будет повторно использовать компонент, когда вы установите область действия для чего-то другого (т. е. вы не должны использовать прототип, сеанс или запрос). Таким образом, хитрость заключается в использовании двух bean-компонентов: один, в котором есть все, что не меняется. И один bean-компонент, который прикреплен к сеансу/запросу и имеет только одну зависимость: первый bean-компонент.

Spring не может сделать это за вас, поскольку нет правила, когда bean-компонент достаточно "статичен" - вы, как разработчик, должны это определить.

[EDIT] Вы должны собрать статические части bean-компонента (те, которые не изменятся со временем) в DAO/сервисный bean-компонент. Затем используйте этот компонент в своем @Component -> одном поиске.

Чтобы ускорить поиск, присвойте компоненту имя. Для поиска на основе типов Spring должен выполнять итерацию по всему контексту (поскольку несколько bean-компонентов могут совпадать), в то время как поиск на основе имени/идентификатора — это просто поиск на карте.

Чтобы дать bean-компоненту имя, укажите его в @Context или используйте @Bean(name="name"). Чтобы указать Spring, какой bean-компонент использовать из контекста, используйте @Resource(name) или @Qualifier("businessObject").

person Aaron Digulla    schedule 22.03.2011
comment
Я уверен, что этот ответ выглядит хорошо, когда он прикреплен к другому вопросу. - person krosenvold; 22.03.2011
comment
@krosenvoid Нет, я бы сказал, что это лучший ответ, который вы можете получить на этот вопрос (+1) - person Sean Patrick Floyd; 22.03.2011

Лучшей практикой является использование классов обслуживания, компонентов, DAO и т. д. в качестве синглетонов и наличие только одного экземпляра в контексте приложения. Аннотация @Component приводит к тому, что в процессе сканирования компонентов будут найдены только экземпляры, что означает, что они являются кандидатами для автоматического -scan и живые экземпляры в весеннем контексте. Например:

@Component
public class StudentDAO {
        @Override
        public String toString() {
                return " inside StudentDAO";
        }
}

StudentDAO — это объект доступа к данным, и в соответствии с передовым опытом в данном контексте не требуется более одного экземпляра этого класса службы. По сути, это сервисный класс. Это идеальный кандидат на синглтон. Если вокруг есть только один экземпляр этого объекта, автосвязывание также работает эффективно 8-). Но вы все равно должны остерегаться доступа к одноэлементным методам и решить пометить свои методы как синхронизированные, чтобы предотвратить нежелательные эффекты потоков.

person Erhan Bagdemir    schedule 22.03.2011

Ручная альтернатива состоит в том, чтобы внедрить в ваши bean-компоненты Provider с одноэлементной областью видимости, который предоставляет bean-компоненты с областью прототипа.

Это означает, что программист выполняет больше работы, но, тем не менее, падение производительности будет устранено.

person Robert Munteanu    schedule 22.03.2011

Установите атрибут proxyMode аннотации @Scope для bean-компонентов с областью запроса/сеанса. Spring создаст прокси-сервер, который будет автоматически подключен - прокси-сервер будет искать фактический компонент, для которого вызывается метод.

person gkamal    schedule 23.03.2011