当前我在控制器和服务层之间的Autowire配置中遇到问题,但是我收到了依赖注入问题。我正在使用JPA开发Spring Boot 2.1.2.RELEASE应用程序。我定义了存储库接口和实施。
UserRepositoryInterface:
set_default_executor
UserSchoolRepositoryInterface:
@Repository
@Transactional
public interface UserRepositoryInterface extends JpaRepository<Account,Long> {
@Query("SELECT a FROM Account a WHERE a.userName = :username")
Account findByLogin(@Param("username") String username);
}
我正在使用Oauth2进行授权。
主要:
@Repository
@Transactional
public interface UserSchoolRepositoryInterface extends JpaRepository<UserSchool, Integer> {
@Query("select s.id " + "from Account u,School s,UserSchool us "
+ "where u.id=?1 " + "and us.userId = u.id "
+ "and us.schoolId = s.id")
Integer findSchoolByUserId(Long id);
}
OAuth2AuthorizationConfig:
@SpringBootApplication
public class Main extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
WebSecurityConfiguration:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Value("${check-user-scopes}")
private Boolean checkUserScopes;
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean
public OAuth2RequestFactory requestFactory() {
CustomOauth2RequestFactory requestFactory = new CustomOauth2RequestFactory(clientDetailsService);
requestFactory.setCheckUserScopes(true);
return requestFactory;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new CustomTokenEnhancer();
converter.setKeyPair(new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "password".toCharArray()).getKeyPair("keystore"));
return converter;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
@Bean
public TokenEndpointAuthenticationFilter tokenEndpointAuthenticationFilter() {
return new TokenEndpointAuthenticationFilter(authenticationManager, requestFactory());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtAccessTokenConverter())
.authenticationManager(authenticationManager).userDetailsService(userDetailsService);
if (checkUserScopes)
endpoints.requestFactory(requestFactory());
}
}
CustomUserDetailsService:
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and().authorizeRequests().antMatchers("/**").authenticated().and().httpBasic();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
CustomOauth2RequestFactory:
@Service(value = "userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepositoryInterface userRepositoryInterface;
@Autowired
private UserRoleRepositoryInterface userRoleRepositoryInterface;
@Autowired
private UserSchoolRepositoryInterface userSchoolRepositoryInterface;
@Override
public UserDetails loadUserByUsername(String input) {
Account user = userRepositoryInterface.findByLogin(input);
if (null == user) {
throw new UsernameNotFoundException(
"INVALID USER WITH LOGIN: " + input);
} else {
List<String> userRoles = userRoleRepositoryInterface.findRoleByUserId(user.getId());
Integer userSchool = userSchoolRepositoryInterface.findSchoolByUserId(user.getId());
return new CustomUserDetails(user, userRoles, userSchool);
}
}
}
下面是我的剩余控制器类和服务。
LoopController:
public class CustomOauth2RequestFactory extends DefaultOAuth2RequestFactory {
@Autowired
private TokenStore tokenStore;
@Autowired
private UserDetailsService userDetailsService;
public CustomOauth2RequestFactory(ClientDetailsService clientDetailsService) {
super(clientDetailsService);
}
@Override
public TokenRequest createTokenRequest(Map<String, String> requestParameters,
ClientDetails authenticatedClient) {
if (requestParameters.get("grant_type").equals("refresh_token")) {
OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(
tokenStore.readRefreshToken(requestParameters.get("refresh_token")));
SecurityContextHolder.getContext()
.setAuthentication(new UsernamePasswordAuthenticationToken(authentication.getName(), null,
userDetailsService.loadUserByUsername(authentication.getName()).getAuthorities()));
}
return super.createTokenRequest(requestParameters, authenticatedClient);
}
}
LoopDao:
@RestController
@RequestMapping("/users")
public class LoopController {
@Autowired
private AccountService accountService;
@Autowired
public LoopDao loopDao;
public static RestTemplate restTemplate = new RestTemplate();
Gson gson;
GsonBuilder builder;
@RequestMapping(value="/checkCategoryName",method=RequestMethod.POST)
public @ResponseBody String checkCategoryName(@RequestBody String categoryName){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Account customUser = accountService.findByUsername(authentication.getPrincipal().toString());
School school = customUser.getUserSchool().getSchoolId();
System.out.println("school : "+school.getName());
String jsonAccts = null;
long count = loopDao.checkCategoryName(categoryName,school.getId());
System.out.println("count "+count);
return (count == 0)? "no" : "yes";
}
}
LoopService:
public interface LoopDao {
long checkCategoryName(String categoryName, int id);
}
build.gradle:
@Service
@Transactional
public class LoopService implements LoopDao {
@Autowired
private SessionFactory sessionFactory;
private org.hibernate.Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
@Override
public long checkCategoryName(String categoryName, int id) {
Session session = getCurrentSession();
try {
long count = (long) session.createQuery("select count(name) from Category where name = :catName and schoolId = :schoolId")
.setParameter("catName", categoryName).setParameter("schoolId", id).uniqueResult();
return count;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
@Override
public int createCategory(Category category) {
Session session = getCurrentSession();
Transaction tx = session.beginTransaction();
try {
Serializable genid = session.save(category);
tx.commit();
return Integer.parseInt(genid.toString());
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
return -1;
}
}
}
application.yml:
group 'com.lss.loopserver'
version '1.0-SNAPSHOT'
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
war {
baseName = 'LoopServer'
version = '0.0.1'
}
sourceCompatibility = 1.8
repositories {
jcenter()
maven { url "http://repo.spring.io/libs-snapshot" }
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.cloud:spring-cloud-starter-oauth2')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-tomcat')
compile('javax.inject:javax.inject:1')
compile ('mysql:mysql-connector-java:6.0.6')
compile ('com.google.code.gson:gson:2.8.1')
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.3'
compile 'org.apache.commons:commons-io:1.3.2'
runtime('org.springframework.boot:spring-boot-devtools')
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Greenwich.RC2"
}
}
bootRun {
sourceResources sourceSets.main
}
我的应用程序不会以以下消息开头:
security:
oauth2:
client:
clientId: clientapp
clientSecret: 123456
authorized-grant-types: authorization_code,refresh_token,password
scope: openid
resource.jwt:
key-pair:
alias: keystore
store-password: password
resource:
token-info-uri: http://192.168.1.2:8333/LoopServer/oauth/token
prefer-token-info: true
server:
port: 8333
servlet:
context-path: /LoopServer
spring:
datasource:
url: jdbc:mysql://${db.host:localhost}:${db.port:3306}/${db.name:loopschool}?useSSL=false
username: ${db.uid:root}
password: ${db.pwd:}
driver-class-name: com.mysql.cj.jdbc.Driver
tomcat:
test-while-idle: true
validation-query: SELECT 1
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
hibernate:
id:
new_generator_mappings: true
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
ddl-auto: validate
application:
name: LoopServer
jmx:
default-domain: LoopServer
servlet:
multipart:
max-file-size: 30MB
max-request-size: 100MB
main:
allow-bean-definition-overriding: true
check-user-scopes: true
debug: true
答案 0 :(得分:0)
最后,我解决了这个问题。 问题是在我从Spring Boot 1.5迁移到Spring Boot 2.1.2之后出现的 较早版本中的大多数功能已被弃用,包括访问sessionfactory的方式。
解决方案: 使用以下代码
@Autowired
private EntityManagerFactory entityManagerFactory;
private org.hibernate.Session getCurrentSession(){
return entityManagerFactory.unwrap(SessionFactory.class).openSession();
}
代替
@Autowired
private SessionFactory sessionFactory;
private org.hibernate.Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
我从this链接获得了解决方案