问题:
如果我们想给UserService注入HikariDataSource,但是这个类位于com.zaxxer.hikari包中,并且HikariDataSource也不可能有@Component注解,如何告诉IoC容器创建并配置HikariDataSource?或者换个说法,如何创建并配置一个第三方Bean?
源码如下:
User
package com.sun.bean;
/**
* @Auther Mario
* @Date 2021-02-23 15:50
* @Version 1.0
* @description
*/
public class User {
private long id;
private String email;
private String password;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(long id, String email, String password, String name) {
this.id = id;
this.email = email;
this.password = password;
this.name = name;
}
}
MailService
package com.sun.service;
import com.sun.bean.User;
import org.springframework.stereotype.Component;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
/**
* @Auther Mario
* @Date 2021-02-23 15:47
* @Version 1.0
* @description
*/
@Component
public class MailService {
private ZoneId zoneId = ZoneId.systemDefault();
public void setZoneId(ZoneId zoneId){
this.zoneId = zoneId;
}
public String getTime(){
return ZonedDateTime.now(this.zoneId).format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
public void sendLoginMail(User user){
System.err.println(String.format("Hi, %s! You are logged in at %s",
user.getName(),getTime()));
}
public void sendRegistrationMail(User user){
System.out.println(String.format("Welcome, %s",user.getName()));
}
}
UserService
package com.sun.service;
import com.sun.bean.User;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @Auther Mario
* @Date 2021-02-23 15:55
* @Version 1.0
* @description
*/
@Component
public class UserService {
@Autowired
private MailService mailService;
@Autowired
private HikariDataSource dataSource;
public void setMailService(MailService mailService) {
this.mailService = mailService;
}
private List<User> users = new ArrayList<>(List.of(
new User(1, "bob@example.com", "password", "Bob"), // bob
new User(2, "alice@example.com", "password", "Alice"), // alice
new User(3, "tom@example.com", "password", "Tom"))); // tom
public User login(String email, String password) throws SQLException, SSLException {
// for (User user : users) {
// if (user.getEmail().equalsIgnoreCase(email) && user.getPassword().equals(password)) {
// mailService.sendLoginMail(user);
// return user;
// }
// }
try (Connection conn = dataSource.getConnection()){
try(PreparedStatement ps = conn.prepareStatement("select * from user")){
try(ResultSet rs = ps.executeQuery()){
while(rs.next()) {
Long dbId = rs.getLong("id");
String dbEmail = rs.getString("email");
String dbPassword = rs.getString("password");
String dbName = rs.getString("name");
if(dbEmail.equals(email) && dbPassword.equals(password)) {
return new User(dbId, dbEmail, dbPassword, dbName);
}
}
throw new RuntimeException("login failed.");
}
}
}
// throw new RuntimeException("login failed.");
}
//查找id
public User getUser(long id){
return this.users.stream().filter(user -> user.getId() == id).
findFirst().orElseThrow();
}
//注册
public User register(String email,String password,String name){
users.forEach((user) -> {
if(user.getEmail().equalsIgnoreCase(email)){
throw new RuntimeException("email exist");
}
});
User user = new User(users.stream().mapToLong(u -> u.getId()).max().getAsLong() + 1,
email,password,name);
users.add(user);
mailService.sendRegistrationMail(user);
return user;
}
}
package com.sun;
import com.sun.bean.User;
import com.sun.service.UserService;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.SSLException;
import java.sql.SQLException;
import java.util.Properties;
/**
* @Auther Mario
* @Date 2021-02-24 10:29
* @Version 1.0
* @description
*/
@Configuration
@ComponentScan
public class AppConfig {
public static void main(String[] args) throws SQLException, SSLException {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) ctx.getBean("userService");
User user = userService.login("bob@example.com", "password");
User mario = new User(4,"mario@sina.com","12345","mario");
userService.register(mario.getEmail(),mario.getPassword(),mario.getName());
System.out.println(user.getName());
}
//使用第三方Bean
@Bean(name = "dataSource")
public HikariDataSource getDataSource(){
Properties props = new Properties();
props.setProperty("jdbcUrl","jdbc:mysql://localhost:3306/springIoc?characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false");
props.setProperty("username","root");
props.setProperty("password","1234");
HikariConfig config = new HikariConfig(props);
config.addDataSourceProperty("cachePrepStmts", "true");
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
}