package com.apobates.forum.thrones.admin; import com.alibaba.druid.pool.DruidDataSource; import com.apobates.forum.core.impl.CoreAppConfig; import com.apobates.forum.letterbox.impl.LetterAppConfig; import com.apobates.forum.member.impl.MemberAppConfig; import com.apobates.forum.utils.Commons; import com.apobates.forum.utils.lang.CommonDoubleBean; import com.apobates.forum.utils.lang.CommonDoubleBeanDeserializer; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableLoadTimeWeaving; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; import redis.clients.jedis.JedisPoolConfig; /** * 后端Spring framework配置类 * @author xiaofanku * @since 20200603 */ @Configuration @PropertySource("classpath:global.properties") @EnableLoadTimeWeaving @EnableAspectJAutoProxy(proxyTargetClass=true) @EnableTransactionManagement(proxyTargetClass = true) @Import(value = {MemberAppConfig.class, LetterAppConfig.class, CoreAppConfig.class, ThronesAdminRedisEventConfig.class}) public class ThronesAdminAppConfig { @Autowired private Environment env; // @Bean public JdbcProperties getJdbcProperties() { JdbcProperties jp = new JdbcProperties(); jp.setDriverClassName(env.getProperty("jdbc.driverClassName")); jp.setUrl(env.getProperty("jdbc.url")); jp.setUsername(env.getProperty("jdbc.username")); jp.setPassword(env.getProperty("jdbc.password")); try { jp.setPoolInit(Integer.valueOf(env.getProperty("jdbc.pool.init"))); } catch (Exception e) { jp.setPoolInit(1); } try { jp.setPoolMinIdle(Integer.valueOf(env.getProperty("jdbc.pool.minIdle"))); } catch (Exception e) { jp.setPoolMinIdle(3); } try { jp.setPoolMaxActive(Integer.valueOf(env.getProperty("jdbc.pool.maxActive"))); } catch (Exception e) { jp.setPoolMaxActive(20); } jp.setPoolTestSql(env.getProperty("jdbc.pool.testSql")); jp.setJpaUnitName(env.getProperty("jpa.unit-name")); return jp; } // 数据源 @Bean(value = "dataSource", initMethod = "init", destroyMethod = "close") // 假如没有指定名字,默认为方法名 public DataSource buildDataSource(JdbcProperties jdbcProperties) { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(jdbcProperties.getDriverClassName()); ds.setUrl(jdbcProperties.getUrl()); ds.setUsername(jdbcProperties.getUsername()); ds.setPassword(jdbcProperties.getPassword()); ds.setInitialSize(jdbcProperties.getPoolInit()); ds.setMinIdle(jdbcProperties.getPoolMinIdle()); ds.setMaxActive(jdbcProperties.getPoolMaxActive()); ds.setMaxWait(60000); ds.setTimeBetweenEvictionRunsMillis(60000); ds.setMinEvictableIdleTimeMillis(300000); ds.setValidationQuery(jdbcProperties.getPoolTestSql()); ds.setTestWhileIdle(true); ds.setTestOnBorrow(false); ds.setTestOnReturn(false); return ds; } //ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) @Bean public JpaVendorAdapter getJpaVendorAdapter() { EclipseLinkJpaVendorAdapter elva = new org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter(); elva.setGenerateDdl(true); elva.setShowSql(true); elva.setDatabase(Database.MYSQL); elva.setDatabasePlatform("org.eclipse.persistence.platform.database.MySQLPlatform"); return elva; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(JdbcProperties jdbcProperties, DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) { LocalContainerEntityManagerFactoryBean aemf = new org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean(); aemf.setPersistenceUnitName(jdbcProperties.getJpaUnitName()); aemf.setDataSource(dataSource); aemf.setPersistenceXmlLocation("classpath:META-INF/persistence.xml"); aemf.setJpaVendorAdapter(jpaVendorAdapter); aemf.setJpaDialect(new org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect()); return aemf; } @Bean public JpaTransactionManager transactionManager(EntityManagerFactory emf) { JpaTransactionManager jtm = new org.springframework.orm.jpa.JpaTransactionManager(); jtm.setEntityManagerFactory(emf); return jtm; } //springcache for redis @Bean public JedisConnectionFactory redisConnectionFactory(Environment env) { String redisHost = env.getProperty("cache.redis.host"); int redisPort = Commons.stringToInteger(()->env.getProperty("cache.redis.port"), 6379); String redisPassword = env.getProperty("cache.redis.password"); int redisDatabase = Commons.stringToInteger(()->env.getProperty("cache.redis.database"), 0); long redisTimeout = Commons.stringToLong(()->env.getProperty("cache.redis.timeout"), 60L); RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(redisHost, redisPort); redisConfig.setPassword(redisPassword); redisConfig.setDatabase(redisDatabase); //pool JedisPoolConfig jedisPoolConfig=new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(100); jedisPoolConfig.setMinIdle(10); jedisPoolConfig.setMaxTotal(1000); jedisPoolConfig.setMaxWaitMillis(1000L); JedisClientConfiguration clientConfig = JedisClientConfiguration.builder() .connectTimeout(Duration.ofSeconds(redisTimeout)) .readTimeout(Duration.ofSeconds(redisTimeout)) .usePooling() .poolConfig(jedisPoolConfig) .build(); return new JedisConnectionFactory(redisConfig, clientConfig); } @Bean public RedisTemplate redisTemplate(RedisConnectionFactory cf, GenericJackson2JsonRedisSerializer valuesRedisSerializer) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(cf); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(valuesRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(valuesRedisSerializer); redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } @Bean public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory, GenericJackson2JsonRedisSerializer valuesRedisSerializer) { RedisCacheConfiguration config = RedisCacheConfiguration .defaultCacheConfig() .entryTtl(Duration.ofDays(1)) .disableCachingNullValues() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valuesRedisSerializer)); return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).build(); } @Bean("valuesRedisSerializer") public GenericJackson2JsonRedisSerializer redisSerializer(){ JavaTimeModule jtm = new JavaTimeModule(); jtm.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); jtm.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); jtm.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); jtm.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); jtm.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); jtm.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); // SimpleModule cusModule = new SimpleModule("CommonDoubleBeanDeserializer"); cusModule.addDeserializer(CommonDoubleBean.class, new CommonDoubleBeanDeserializer()); ObjectMapper mapper = new ObjectMapper() .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) .registerModule(jtm) .registerModule(new Jdk8Module()) .registerModule(cusModule) .findAndRegisterModules() .activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return new GenericJackson2JsonRedisSerializer(mapper); } }