SpringBoot Starter设计

SpringBoot重要组件是各种Starter,需要定制扩展SpringBoot功能,必须自定义Starter。本例自定义Starter只使用与SpringBoot 2.x以后版本,实现Redis缓存管理,文件上传基本服务,使用JDBC操作数据库。

定义Maven工程,定义POM依赖


  4.0.0

  com.gufang
  mystarter-spring-boot-starter
  0.0.1-SNAPSHOT
  jar

  mystarter-spring-boot-starter
  http://maven.apache.org


	
		
		UTF-8
		1.8

		
		1.5.10.RELEASE

		
		3.7.0
		2.20.1
		3.0.1
		3.0.0
		1.6
	

	
		
			org.springframework.boot
			spring-boot-starter
			true
		
		
			org.springframework.boot
			spring-boot-configuration-processor
			true
		
		
			junit
			junit
			test
		
		
		    redis.clients
		    jedis
		    2.9.0
		
		
		    com.alibaba
		    fastjson
		    1.2.54
		
		
		    com.fasterxml.jackson.core
		    jackson-databind
		    2.9.8
		
		
		    com.fasterxml.jackson.core
		    jackson-annotations
		    2.9.0
		
		
		    org.springframework.data
		    spring-data-redis
		    2.1.6.RELEASE
		
		
		    org.springframework
		    spring-web
		    5.1.6.RELEASE
		
		
		    javax.servlet
		    javax.servlet-api
		    4.0.0
		    provided
		
	

	
		
			
				org.springframework.boot
				spring-boot-dependencies
				${spring-boot.version}
				pom
				import
			
		
	

	
		
			
				org.apache.maven.plugins
				maven-compiler-plugin
				${maven-compiler-plugin.version}
				
					${project.build.sourceEncoding}
					${java.version}
					${java.version}
				
			
		
	


定义配置文件操作类

本例重用了SpringBoot-data-jdbc-starter配置信息

package com.gufang;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;


@ConfigurationProperties(prefix="spring.datasource")
public class MyStarterProperties {
	private String driverClassName = null;
	private String url = null;
	private String username = null;
	private String password = null;
	
	private String redishost=null;
	private String redisport=null;

	public String getDriverClassName() {
		return driverClassName;
	}
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getRedishost() {
		return redishost;
	}
	public void setRedishost(String redishost) {
		this.redishost = redishost;
	}
	public String getRedisport() {
		return redisport;
	}
	public void setRedisport(String redisport) {
		this.redisport = redisport;
	}

}

使能注解

package com.gufang;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableMyStarterConfiguration {

}

自配置类

package com.gufang;

import java.time.Duration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
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.core.RedisTemplate;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;


@Configuration //向Spring容器配置对象
@ConditionalOnBean(annotation=EnableMyStarterConfiguration.class)
//当Spring容器中包含EnableMyStarterConfiguration声明对象时,进行配置MyStarterAutoConfiguration
@EnableConfigurationProperties(MyStarterProperties.class)
@ServletComponentScan
@EnableCaching
public class MyStarterAutoConfiguration {
	@Autowired
	private MyStarterProperties prop;
	
	@Bean
	public MyConnection createConnecton()
	{
		String className=prop.getDriverClassName();
		String user=prop.getUsername();
		String pwd=prop.getPassword();
		String url=prop.getUrl();
		String redishost=prop.getRedishost();
		String redisport=prop.getRedisport();
		return new MyConnection(className,url,user,pwd,redishost,redisport);
	}
	
	/**
	* 生成Redis的键值,根据类名+方法名+参数值的形式
	* @return
	*/
    @Bean(name = "keyGenerator")
    public KeyGenerator keyGenerator() {
        return new KeyGenerator(){
            @Override
            public Object generate(Object target, java.lang.reflect.Method method, 
                    Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for(Object obj:params){
                    if(obj != null)
                    {
                    	sb.append("_");
                        sb.append(obj.toString());
                    }
                }
                return sb.toString();
            }
        };
    }
    

    @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    	// 设置缓存有效期
    	RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
    				.entryTtl(Duration.ofSeconds(100000000000L));
    	return RedisCacheManager
    	.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
    	.cacheDefaults(redisCacheConfiguration).build();

    }

    @Bean
    @SuppressWarnings({"rawtypes", "unchecked"})
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){
        RedisTemplate redisTemplate=new RedisTemplate();
        redisTemplate.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerializer替换默认的序列化规则
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper=new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);


        //设置value的序列化规则
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        //设置key的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    
  
//	/**
//	 * 生成CacheManager对象
//	* @param redisTemplate
//	* @return
//	*/
//	  @Bean 
//	  public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
//	      RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
//	      cacheManager.setDefaultExpiration(10000);
//	      return cacheManager;
//	  }
//	
//		/**
//	 * 生成Redis内存管理模板,注解@Primary代表此对象是同类型对象的主对象,优先被使用
//	* @param factory
//	* @return
//	*/
//	  @Primary
//	  @Bean
//	  public RedisTemplate redisTemplate(RedisConnectionFactory factory){
//	      RedisTemplate template = new RedisTemplate();
//	      template.setKeySerializer(new StringRedisSerializer());
//	      template.setConnectionFactory(factory);
//	      setSerializer(template);
//	      template.afterPropertiesSet();
//	      return template;
//	  }

	/**
	 * 序列化Redis的键和值对象
	* @param template
	*/
    private void setSerializer(RedisTemplate template){
        @SuppressWarnings({ "rawtypes", "unchecked" })
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = 
            new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
     }
    
    @Bean
    public MyRedisTool createRedisTool()
    {
    	return new MyRedisTool();
    }
    
    @Bean
    public MyFileTool createFileTool()
    {
    	return new MyFileTool();
    }
}

数据库操作类

package com.gufang;

import java.sql.Statement;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gufang.model.FileInfo;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class MyConnection {
	private String className,url,user,pwd,redishost,redisport = null;
	
	public MyConnection(String className,String url,String user,String pwd,
			String redishost,String redisport)
	{
		this.className= className;
		this.url= url;
		this.user= user;
		this.pwd= pwd;
		this.redishost=redishost;
		this.redisport=redisport;
		
		//检查数据库表T_FILE是否存在
		createFileTable();
	}
	
	public Connection getConnection()
	{
		try {
			Class.forName(className);
			return DriverManager.getConnection(url, user, pwd);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public List query(String sql)
	{
		try {
			Connection conn=getConnection();
			Statement statement=conn.createStatement();
			ResultSet rs=statement.executeQuery(sql);
			java.sql.ResultSetMetaData rsmData=rs.getMetaData();
			List lst=new ArrayList();
			while(rs.next())//结果集指针
			{
				int cols=rsmData.getColumnCount();
				Map map=new HashMap();
				for(int i=1;i<=cols;i++)
				{
					String colName=rsmData.getColumnName(i);
					String val=rs.getString(colName);
					map.put(colName, val);
				}
				lst.add(map);
			}
			rs.close();
			statement.close();
			conn.close();
			return lst;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private void createFileTable()
	{
		try {
			Connection conn=getConnection();
			Statement statement=conn.createStatement();
			String checkSql = "select id from T_FILE";
			try {
				statement.execute(checkSql);
				System.out.println("######################################################");
				System.out.println("###数据库表    T_FILE已经存在                                                                                          ###");
				System.out.println("######################################################");
			} catch (Exception e) {
				String createSql = "create table T_FILE(id long,"+
						"name varchar(200),contexttype varchar(100),length bigint,dt date,content mediumblob)";
				statement.execute(createSql);
				System.out.println("######################################################");
				System.out.println("###数据库表    T_FILE被创建                                                                                              ###");
				System.out.println("######################################################");
			}
			statement.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void saveFileInfo(FileInfo fi)
	{
		try {
			Connection conn=getConnection();
			String sql = "insert into T_FILE(id,name,contexttype,length,dt,content)"+
					"values(?,?,?,?,?,?)";
			PreparedStatement pstat = conn.prepareStatement(sql);
			long id = System.currentTimeMillis();
			fi.setId(id);
			pstat.setLong(1, fi.getId());
			pstat.setString(2, fi.getName());
			pstat.setString(3, fi.getContextType());
			pstat.setLong(4, fi.getLength());
			pstat.setDate(5, new Date(System.currentTimeMillis()));
			
			Blob blob = conn.createBlob();
			OutputStream out = blob.setBinaryStream(1); 
			out.write(fi.getContent());
			out.close();
			pstat.setBlob(6, blob); 
			
			pstat.executeUpdate();
			pstat.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public FileInfo getFileInfoById(Long id)
	{
		try {
			FileInfo fi = new FileInfo();
			Connection conn=getConnection();
			String sql = "select * from T_FILE where id=?";
			PreparedStatement pstat = conn.prepareStatement(sql);
			pstat.setLong(1, id);
			ResultSet rs = pstat.executeQuery();
			if(rs.next())
			{
				fi.setId(id);
				fi.setName(rs.getString("name"));
				fi.setContextType(rs.getString("contexttype"));
				fi.setDt(rs.getDate("dt"));
				fi.setLength(rs.getLong("length"));
				Blob blob = rs.getBlob("content") ;
				InputStream input = blob.getBinaryStream();
				byte[] data = new byte[1024];
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				int pos = 0;
				while((pos=input.read(data))!=-1)
					baos.write(data,0,pos);
				fi.setContent(baos.toByteArray());
			}
			pstat.close();
			conn.close();
			return fi;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}

文件操作类

package com.gufang;

import java.io.InputStream;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.gufang.model.FileInfo;


public class MyFileTool {
	@Autowired
	private MyConnection conn;
	
	public FileInfo uploadFile(HttpServletRequest req)
	{
		if(!(req instanceof MultipartHttpServletRequest))
			return null;
		MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req;
		MultipartFile multipartFile = mreq.getFile("file");
		try
		{
			InputStream is = multipartFile.getInputStream();
			byte[] bytes = FileCopyUtils.copyToByteArray(is);
			FileInfo fi = new FileInfo();
			fi.setName(multipartFile.getName());
			fi.setContextType(multipartFile.getContentType());
			fi.setLength(new Long(multipartFile.getBytes().length));
			fi.setContent(bytes);
			conn.saveFileInfo(fi);
			return fi;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}

其他类通过源码下载
https://pan.baidu.com/s/1BUs_3qT1XaS64Y3w3iCZRg

项目中使用自定义Starter

通过注解方式使用Redis

SpringBoot Starter设计_第1张图片
修改Application.properties配置文件
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
#spring.redis.timeout=0

SpringBoot Starter设计_第2张图片
SpringBoot Starter设计_第3张图片

文件上传

SpringBoot Starter设计_第4张图片
SpringBoot Starter设计_第5张图片
SpringBoot Starter设计_第6张图片
SpringBoot Starter设计_第7张图片
SpringBoot Starter设计_第8张图片
SpringBoot Starter设计_第9张图片

你可能感兴趣的:(SpringBoot)