В качестве альтернативы вы можете использовать gem Protected Attributes gem , однако это наносит ущерб требованию сильных параметров. Однако, если вы обновляете более старое приложение, защищенные атрибуты предоставляют простой путь для обновления до тех пор, пока вы не сможете реорганизовать attr_accessible на сильные параметры.
С пружиной 4 возможно автоподключение
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepositroy repositroy;
@Autowired
private UserService userService;
@Override
public void update(int id){
repository.findOne(id).setName("ddd");
}
@Override
public void save(Users user) {
repositroy.save(user);
userService.update(1)l
}
}
Это ограничение с Spring AOP. (динамические объекты и CGLIB)
Если вы настроите Spring на использование AspectJ для обработки транзакций, ваш код будет работать.
Простая и, вероятно, лучшая альтернатива - реорганизовать ваш код. Например, один класс, который обрабатывает пользователей, и один, обрабатывающий каждого пользователя. Тогда обработка транзакций по умолчанию с Spring AOP будет работать.
Советы по настройке для обработки транзакций с AspectJ
Чтобы включить Spring для использования AspectJ для транзакций, вы должны установить режим AspectJ:
<tx:annotation-driven mode="aspectj"/>
Если вы используете Spring с более старой версией, чем 3.0, вы также должны добавить это в свою конфигурацию Spring:
<bean class="org.springframework.transaction.aspectj
.AnnotationTransactionAspect" factory-method="aspectOf">
<property name="transactionManager" ref="transactionManager" />
</bean>
Это мое решение для самозапуска.
private SBMWSBL self;
@Autowired private ApplicationContext applicationContext;
@PostConstruct
public void postContruct(){
self =applicationContext.getBean(SBMWSBL.class);
}
Проблема заключается в том, что прокси-серверы AOP Spring не распространяются, а скорее завершают ваш экземпляр службы, чтобы перехватывать вызовы. Это приводит к тому, что любой вызов «этого» из вашего экземпляра службы непосредственно вызывается в этом экземпляре и не может быть перехвачен прокси-сервером (прокси-сервер даже не знает о таком вызове). Уже упоминалось одно решение. Еще одним из излюбленных было бы просто заставить Spring вставить экземпляр службы в саму службу и вызвать ваш метод на введенном экземпляре, который будет прокси-сервером, который обрабатывает ваши транзакции. Но имейте в виду, что это может иметь и плохие побочные эффекты, если ваш сервисный компонент не является одиночным:
<bean id="userService" class="your.package.UserService">
<property name="self" ref="userService" />
...
</bean>
public class UserService {
private UserService self;
public void setSelf(UserService self) {
this.self = self;
}
@Transactional
public boolean addUser(String userName, String password) {
try {
// call DAO layer and adds to database.
} catch (Throwable e) {
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
}
}
public boolean addUsers(List<User> users) {
for (User user : users) {
self.addUser(user.getUserName, user.getPassword);
}
}
}
Вы можете авторизовать BeanFactory внутри одного класса и делать
getBean(YourClazz.class)
. Он автоматически проксимизирует ваш класс и учитывает вашу @Transactional или другую аннотацию aop.
Проблема связана с тем, как классы весенней нагрузки и прокси. Это не сработает, пока вы не напишете свой внутренний метод / транзакцию в другом классе или не перейдете к другому классу, а затем снова придете к вашему классу и затем напишите внутренний метод вложенной транскокации.
Подводя итог, весенние прокси делают не разрешайте сценарии, с которыми вы сталкиваетесь. вам необходимо написать второй метод транзакции в другом классе