2016-02-02 2 views
1

У меня есть класс Employee, который синглтон, как определено в spring.xmlКак работает геттер (Singleton Bean) в случае, если мы вставляем прототип bean в singleton bean через доверенный прокси-сервер?

public class Employee{ 
private Vehicle vehicle; 
public Vehicle getVehicle() { 
    return vehicle; 
} 
public void setVehicle(Vehicle vehicle) { 
    this.vehicle = vehicle; 
} 
} 

У меня есть класс автомобиля, который является прототипом, как это определено в spring.xml

public class Vehicle { 
private String name; 
public String getName() { 
    return name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
} 

Ниже приводится spring.xml

<bean id="employee" class="com.example.factory.Employee"> 
<property name="vehicle" ref="vehicle"></property> 
</bean> 
<bean id="vehicle" class="com.example.factory.Vehicle" scope="prototype"> 
<property name="name" value="car"></property> 
<aop:scoped-proxy /> 
</bean> 

Теперь я знаю, что весна создаст прокси для автомобиля. Каждый раз, когда я вызываю getVehicle() на объект employee, я получаю новый объект Vehicle. Но в методе getVehicle() я не создаю новый объект Vehicle, и, согласно моему пониманию, Spring не создает прокси для объекта Employee. Итак, кто-то, пожалуйста, заставьте меня детально понять, что происходит внутри, и как работает getVehicle()?

+0

Фактически 'getVehicle()' всегда возвращает тот же объект, который фактически является прокси-сервером для фактического экземпляра 'Vehicle'. Для каждого вызова метода, который вы делаете на «Vehicle», вы получите новый экземпляр, потому что это то, что вы сказали ему, чтобы сделать с scoped-прокси и «scope = prototype». В принципе, прокси-сервер с ограниченной видимостью не имеет смысла для «scope = prototype» только для областей «запрос» и «сеанс» (и некоторых других, которые не предоставляются по умолчанию). –

+0

, если 'getVehicle()' всегда возвращает один и тот же объект, то почему при выполнении этого оператора 'System.out.println (getVehicle())' каждый раз выводит другой хэш-код? – lavish

+0

Поскольку он возвращает прокси вместо фактического объекта, прокси-сервер всегда один и тот же. Метод 'hashCode' передается фактическому базовому объекту (в основном с использованием' hashCode', чтобы проверить, является ли он одним и тем же объектом, не очень хорошо, особенно если не используются прокси-серверы). –

ответ

0

Вы не получаете новый экземпляр автомобиля каждый раз, когда вы вызываете getVehicle(). Вы получаете новый экземпляр Vehicle каждый раз, когда Spring должен его предоставить. Это может произойти двумя способами:

  1. Вы спрашиваете Spring для боба автомобиля
  2. Spring autowires Автомобиля в бобе Сотрудника. Это происходит только один раз, поскольку Employee - одноэлементный. Так что, если это единственный способ, который используется для транспортного средства, он может также быть синглом.

См. this page для более подробного объяснения.

+0

Ну да и нет. Это прокси-сервер с прототипом области видимости, который в этом случае означает, что введенный прокси-сервер вводится, и каждый вызов метода на «Vehicle» приведет к новому экземпляру. Ключевым моментом здесь является тот факт, что это прокси-сервер, а не обычный прототип. –

0

Ниже мои выводы по этим

Я изменил определение бин для транспортного средства путем удаления инициализации, как показано ниже.

<bean id="employee" class="com.emp.Employee"> 
<property name="vehicle" ref="vehicle"></property> 
</bean> 

<bean id="vehicle" class="com.emp.Vehicle" scope="prototype"> 
<aop:scoped-proxy /> 
</bean> 

И я создал тестовый класс для этого сценария

Смотрите ниже код

public class TestScope { 

    @Autowired 
    Employee employee = null; 

    @Test 
    public void testScope() 
    { 

     employee.getVehicle().setName("bike"); 
     System.out.println("vehicle name:"+employee.getVehicle().getName()); 


    } 
    } 

С выше код работает, выход ниже

vehicle name:null 

Но если я изменю область действия класса «По умолчанию» (singleton), я получаю следующий результат:

vehicle name:bike 

Так заключить, для каждого employee.getVehicle() есть новый экземпляр автомобиля, созданного, так как это явно указано в определении боба, чтобы сделать это, и прокси-сервер передаст этот объект. Но если мы удалим определение области, оно будет одноточечным и создаст единый объект, который останется неизменным в течение жизненного цикла компонента.

+0

, пожалуйста, обратитесь к [link] (http://stackoverflow.com/questions/14371335/spring-scoped-proxy-bean), который я нахожу более полезным в этой теме. –

+0

Эй, это мой вопрос. Я знаю это. Я спрашиваю, как весна это делает? – lavish

Смежные вопросы