문제

I am using spring3. I have below classes.

Transport.java

package com.net.core.ioc;

public interface Transport {
  public void doSave();
}

Car.java

package com.net.core.ioc;

    public class Car implements Transport{
     String name;
     public Car(String name){
         this.name=name;
      }
        public void doSave(){
            //saving logic using name
        }
    }

Bus.java

package com.net.core.ioc;

    public class Bus implements Transport {
      String id;
      public Bus(String id){
         this.id=id;
      }
        public void doSave() {
            //saving logic using id
        }

SpringService.java

package com.net.core.ioc;

    public class ServiceLocator {
        private static ServiceLocator service = new ServiceLocator ();

        //Static factory method
        public static ServiceLocator createService(){
            return service;
        }

        //Instance factory methods
        public Transport createCarInstance(String name){
        return new Car(name);
        }

    public Transport createBusInstance(String id){
            return new Bus(id);
        }

    }
 }

config.xml

<context:component-scan base-package="com.net.core.ioc"/>
        <bean id="serviceLocator" class="com.net.core.ioc.ServiceLocator"factory-method="createService"/>
        <bean id="springServiceCarInstance" factory-bean="serviceLocator" factory-method="createCarInstance" scope="prototype"/>
        <bean id="springServiceBusInstance" factory-bean="serviceLocator" factory-method="createBusInstance" scope="prototype"/>
    </beans>

Now i am getting beans as below:

Transport request = (Transport)applicationContext.getBean("springServiceCarInstance","someName");
request.doSave();

Now can i use spring transactions here ? I mean can i annotate Car and Bus classes using @Transactional ?

도움이 되었습니까?

해결책

No. Since car and bus are not created by the spring factory, the instances you get will not be transaction weaved proxies so the annotations would be pointless.

You want to create it via the spring context using initializeBean or createBean. For more details, look at the java doc on AutoWireCapableBeanFactory.

Alternately you can register Can and Bus with spring context as prototype beans, and just use getBean( "beanName", BeanType.class ) and spring will always return you new instances of them.

@Component
@Scope("singleton")
public class CarFactory {

    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    public Car create( Make make, Model model, Year year ) {
        Car car = new Car( make, model, year );

        // this will apply the post processors including ones that might wrap the original bean
        // such as transaction interceptors etc.
        Car carProxy = Car.class.cast(autowireCapableBeanFactory.configureBean(car, "carBean"));
        return carProxy;
    }
}

다른 팁

Car and Bus are entities in the object model. Entities are normally not transactional. Create a repository/service bean capable of persisting these entity types and then make that bean transactional.

This would allow you to remove the doSave method which would eliminate the need for these entities to be declared as beans.

@Component
public class CarRepository{

    @Transactional
    public void doSave(Car car){

    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top