在 Controller 中注入 SessionScope bean 不起作用
Injecting a SessionScope bean in Controller not working
我在设置属性值时遇到问题,即。 shortname
到 Spring Boot.
中的 SessionScope bean
这是我的 class:
import java.util.Map;
public class LdapUser {
private String shortname = "";
private Map<String,String> token = null;
private String id = "";
public LdapUser() {
}
public String getshortname() {
return shortname;
}
public void setshortname(String shortname) {
this.shortname = shortname;
}
... remaining geters and setters
我的 Bean 定义在这里:
import xxx.controllers.SwitchController;
import xxx.isim.LdapUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public LdapUser sessionScopedLdapUser() {
logger.info("LdapUser bean instance created");
return new LdapUser();
}
}
我在控制器中使用 Bean:
import xxx.errors.IsimConnectionException;
import xxx.isim.IsimConnection;
import xxx.isim.LdapUser;
import xxx.services.IsimRestApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.security.Principal;
@Controller
public class HomeController {
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@Resource(name = "sessionScopedLdapUser")
LdapUser sessionScopedLdapUser;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
/
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
sessionScopedLdapUser.setshortname(shortname); //<-----
我的 Bean 的 shortname
值在带有箭头的行之后仍然为空,即使我正确地获得了 shortname
字符串值并且该值不为空。你能指出我在设置 bean 属性值时做错了什么吗?我按照示例 here for SessionScope Beans
更新:
我还尝试使用 autowired 而不是 @Resource(name = "sessionScopedLdapUser") 但执行后该值仍然为 null sessionScopedLdapUser.setshortname(shortname);
@Autowired
LdapUser sessionScopedLdapUser
我还在日志中看到 LdapUser bean 实例被创建了三次。这怎么可能?
2021-09-21 10:55:55,469 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
2021-09-21 10:57:05,247 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
2021-09-21 10:58:08,401 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
想法是每个 HTTP 会话有一个 bean。我真的很困惑,希望得到一些提示。我正在阅读这篇文章 article,也许那是因为我正在尝试将会话范围 bean 注入到 Singletone bean。
我的文件结构是:
xxx
---auth
---config
--- RestRemplateClient
---controllers
--- HomeController
---errors
---isim
--- LdapUser
---services
Mainapp
您可以指定您的配置如下:-
import org.springframework.context.annotation.Scope;
import java.time.LocalDateTime;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class LdapUser {
private String shortName = "LdapUser Session Scope";
// other properties
public LdapUser() {
System.out.println("LdapUser SessionScope Constructor Called at "+LocalDateTime.now());
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
}
配置中:
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Autowired
private LdapUser ldapUser;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public void setLdapUser(LdapUser ldapUser) {
this.ldapUser = ldapUser;
}
public LdapUser getLdapUser() {
return ldapUser;
}
}
并进入您的控制器:-
@Controller
public class HomeController {
// Other Codes
@Autowired
private RestTemplateClient restTemplateClient;
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
/
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
restTemplateClient.getLdapUser().setShortName("LdapUser Session Scope Updated");
// .... Other codes
}
}
}
感谢@M。 Deinum 我能够弄清楚。我正在查看调试器中的字段值,并且那个字段值始终为空,因为我正在查看代理而不是真实对象。
这是在@Controller class 中注入 session 作用域 bean 的代码。它也可以在@Service class.
中以相同的方式正常工作
public class LdapUser {
private String shortname = "";
private Map<String,String> token = new HashMap<>();
private String id = "";
public LdapUser() {
this.shortname = shortname;
this.token = token;
this.id = id;
}
public String getshortname() {
return shortname;
}
public void setshortname(String shortname) {
this.shortname = shortname;
}
... other getters and setters
我的 bean 配置 class:
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
@SessionScope
public LdapUser sessionScopedLdapUser() {
logger.info("LdapUser bean instance created at "+ LocalDateTime.now());
return new LdapUser();
}
}
我的控制器class:
@Controller
public class HomeController {
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@Autowired
LdapUser sessionScopedLdapUser;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
//System.out.println("******* USER IS " + authentication.getPrincipal());
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
sessionScopedLdapUser.setshortname(shortname);
我在设置属性值时遇到问题,即。 shortname
到 Spring Boot.
这是我的 class:
import java.util.Map;
public class LdapUser {
private String shortname = "";
private Map<String,String> token = null;
private String id = "";
public LdapUser() {
}
public String getshortname() {
return shortname;
}
public void setshortname(String shortname) {
this.shortname = shortname;
}
... remaining geters and setters
我的 Bean 定义在这里:
import xxx.controllers.SwitchController;
import xxx.isim.LdapUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public LdapUser sessionScopedLdapUser() {
logger.info("LdapUser bean instance created");
return new LdapUser();
}
}
我在控制器中使用 Bean:
import xxx.errors.IsimConnectionException;
import xxx.isim.IsimConnection;
import xxx.isim.LdapUser;
import xxx.services.IsimRestApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.security.Principal;
@Controller
public class HomeController {
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@Resource(name = "sessionScopedLdapUser")
LdapUser sessionScopedLdapUser;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
/
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
sessionScopedLdapUser.setshortname(shortname); //<-----
我的 Bean 的 shortname
值在带有箭头的行之后仍然为空,即使我正确地获得了 shortname
字符串值并且该值不为空。你能指出我在设置 bean 属性值时做错了什么吗?我按照示例 here for SessionScope Beans
更新:
我还尝试使用 autowired 而不是 @Resource(name = "sessionScopedLdapUser") 但执行后该值仍然为 null sessionScopedLdapUser.setshortname(shortname);
@Autowired
LdapUser sessionScopedLdapUser
我还在日志中看到 LdapUser bean 实例被创建了三次。这怎么可能?
2021-09-21 10:55:55,469 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
2021-09-21 10:57:05,247 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
2021-09-21 10:58:08,401 INFO [http-nio-8080-exec-4] xxx.config.RestTemplateClient: LdapUser bean instance created
想法是每个 HTTP 会话有一个 bean。我真的很困惑,希望得到一些提示。我正在阅读这篇文章 article,也许那是因为我正在尝试将会话范围 bean 注入到 Singletone bean。
我的文件结构是:
xxx
---auth
---config
--- RestRemplateClient
---controllers
--- HomeController
---errors
---isim
--- LdapUser
---services
Mainapp
您可以指定您的配置如下:-
import org.springframework.context.annotation.Scope;
import java.time.LocalDateTime;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class LdapUser {
private String shortName = "LdapUser Session Scope";
// other properties
public LdapUser() {
System.out.println("LdapUser SessionScope Constructor Called at "+LocalDateTime.now());
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
}
配置中:
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Autowired
private LdapUser ldapUser;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public void setLdapUser(LdapUser ldapUser) {
this.ldapUser = ldapUser;
}
public LdapUser getLdapUser() {
return ldapUser;
}
}
并进入您的控制器:-
@Controller
public class HomeController {
// Other Codes
@Autowired
private RestTemplateClient restTemplateClient;
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
/
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
restTemplateClient.getLdapUser().setShortName("LdapUser Session Scope Updated");
// .... Other codes
}
}
}
感谢@M。 Deinum 我能够弄清楚。我正在查看调试器中的字段值,并且那个字段值始终为空,因为我正在查看代理而不是真实对象。
这是在@Controller class 中注入 session 作用域 bean 的代码。它也可以在@Service class.
中以相同的方式正常工作public class LdapUser {
private String shortname = "";
private Map<String,String> token = new HashMap<>();
private String id = "";
public LdapUser() {
this.shortname = shortname;
this.token = token;
this.id = id;
}
public String getshortname() {
return shortname;
}
public void setshortname(String shortname) {
this.shortname = shortname;
}
... other getters and setters
我的 bean 配置 class:
@Configuration
public class RestTemplateClient {
Logger logger = LoggerFactory.getLogger(SwitchController.class);
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
@SessionScope
public LdapUser sessionScopedLdapUser() {
logger.info("LdapUser bean instance created at "+ LocalDateTime.now());
return new LdapUser();
}
}
我的控制器class:
@Controller
public class HomeController {
private static final Logger log = LoggerFactory.getLogger(HomeController.class);
@Autowired
IsimRestApiService isimConn;
@Autowired
LdapUser sessionScopedLdapUser;
@RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
//System.out.println("******* USER IS " + authentication.getPrincipal());
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
// set the shortname for the session
String shortname = (String)authentication.getPrincipal();
sessionScopedLdapUser.setshortname(shortname);