关于springboot使用Scope为request或session时:
controller代码: @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService;
}
service代码:
@Service @Transactional @Scope("request") public class UserServiceImpl, UserService {
}
由于controller在spring初始化IOC容器创建的bean默认是单例,当service注入到controller时,service的作用域为web应用的request,而IOC初始化时岂不是是把web应用的第一个request注入给controller,而之后的不会在注入给controller,所以此时springboot就会抛出异常,而这里只需要一个小改定就可以解决问题。
@Service @Transactional @RequestScope(proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserServiceImpl, UserService {
}
spring的scope有扩充了RequestScope和@SessionScope,里面是对原有的Scope进行扩展,request和session的域和默认的代理模式TARGET_CLASS。
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Scope(WebApplicationContext.SCOPE_REQUEST) public @interface RequestScope { /** * Alias for {@link Scope#proxyMode}. * <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}. */ @AliasFor(annotation = Scope.class) ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; }
这里可以看下RequestScope源码中有一个ScopedProxyMode代理方式的属性
ScopedProxyMode代理方式里面分为4种:
/** * Default typically equals {@link #NO}, unless a different default * has been configured at the component-scan instruction level. */ DEFAULT, /** * Do not create a scoped proxy. * <p>This proxy-mode is not typically useful when used with a * non-singleton scoped instance, which should favor the use of the * {@link #INTERFACES} or {@link #TARGET_CLASS} proxy-modes instead if it * is to be used as a dependency. */ NO, /** * Create a JDK dynamic proxy implementing <i>all</i> interfaces exposed by * the class of the target object. */ INTERFACES, /** * Create a class-based proxy (uses CGLIB). */ TARGET_CLASS;