编程杂谈

新博客:https://blog.bigdataboy.cn/article/448.html管理第三方Bean第三方Bean没有办法写给它注解,所以就只能添加,Spring的处理是在配置类中写一个函数,该函数使用@Beam注解第三方Bean配置类第三方Bean的配置类,建议单独文件编写,这样不冗余,全部写一个配置类,会变得一大坨importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjavax.sql.DataSource;@ConfigurationpublicclassJdbcConfig{@Bean//表示返回一个Bean,也可以指定id->@Bean("dataSource")publicDataSourcedataSource(){//参数先空着DruidDataSourcedataSource=newDruidDataSource();dataSource.setDriverClassName("");dataSource.setUrl("");dataSource.setUsername("");dataSource.setPassword("");returndataSource;}}在主配置类导入第三方配置类@Configuration@ComponentScan({"cn.bigdataboy.dao"})@Import({JdbcConfig.class})//导入publicclassSpringConfig{}获取第三方Bean第三方Bean的注入资源上面的例子,JDBC的链接还空着,所以我们需要为其注入参数注入简单类型注入方式与注入自己的Bean一样,使用成员属性添加@Value()注解importcn.bigdataboy.dao.NameDao;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjavax.sql.DataSource;@ConfigurationpublicclassJdbcConfig{@Value("${jdbc.driver}")publicStringdriverClassName;@Value("${jdbc.url}")publicStringurl;@Value("${jdbc.username}")publicStringusername;@Value("${jdbc.password}")publicStringpassword;@Bean//表示返回一个Bean,也可以指定id->@Bean("dataSource")publicDataSourcedataSource(){System.out.println(this.driverClassName);System.out.println(this.url);DruidDataSourcedataSource=newDruidDataSource();dataSource.setDriverClassName(this.driverClassName);dataSource.setUrl(this.url);dataSource.setUsername(this.username);dataSource.setPassword(this.password);returndataSource;}}注入引入类型这里注入引入类型,有点不一样,直接添加成方法参数就好,因为Spring容器中已经存在相应的Bean,那么它也就能自己找到,因此也容易想到它是使用类型方式找的importcn.bigdataboy.dao.NameDao;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjavax.sql.DataSource;@ConfigurationpublicclassJdbcConfig{@Bean//表示返回一个Bean,也可以指定id->@Bean("dataSource")publicDataSourcedataSource(NameDaonameDao){//添加成参数System.out.println(nameDao);//打印一下,表示注入成功DruidDataSourcedataSource=newDruidDataSource();//相应配置returndataSource;}}案例代码:https://pan.bigdataboy.cn/s/NO5sp

编程杂谈

新博客:https://blog.bigdataboy.cn/article/444.html注解开发配置文件的作用降低,只需要完成扫描器的定义就行,类上添加一个注解,就表示该类是容器管理的Bean类添加注解importcn.bigdataboy.service.NameService;importorg.springframework.stereotype.Component;@Component("nameService")//参数就是idpublicclassNameServiceImplimplementsNameService{publicvoidsave(){System.out.println("servicesave...");}}类注解的官方推荐使用importorg.springframework.stereotype.Controller;importorg.springframework.stereotype.Repository;importorg.springframework.stereotype.Service;importorg.springframework.stereotype.Component;@Controller//表现层@Service//业务层@Repository//数据层@Component("nameService")//其他层配置添加扫描器<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--定义扫描器上面的命名空间要完整,idea自动的生成的不完整--><context:component-scanbase-package="cn.bigdataboy"/></beans>纯注解开发不再需要配置文件,所以也很容易想到,配置文件转变成配置类,同时也就能想到,在初始化容器时,传入的也就不是配置文件,而是配置类了配置类格式importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;@Configuration//表示配置类@ComponentScan({"cn.bigdataboy.dao","cn.bigdataboy.service"})//扫描器定义多个路径,可以通配,建议准确一点,毕竟有些类不建议Bean化publicclassSpringConfig{}使用importcn.bigdataboy.config.SpringConfig;importcn.bigdataboy.dao.NameDao;importcn.bigdataboy.service.NameService;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAppForAnnotation{publicstaticvoidmain(String[]args){//加载配置类AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(SpringConfig.class);//从容器获取对象NameServicenameService=(NameService)context.getBean("nameService");NameDaonameDao=context.getBean("nameDao",NameDao.class);System.out.println(nameService);System.out.println(nameDao);}}案例代码:https://pan.bigdataboy.cn/s/y4jie

编程杂谈

新博客:https://blog.bigdataboy.cn/article/443.htmlsetter注入setter注入方式,就是Spring利用对象的set方法,结合书写配置的规则进行注入对象的格式添加set方法publicclassNameServiceImplimplementsNameService{privateNameDaonameDao;publicStringname;//简单类型注入publicvoidsetName(Stringname){this.name=name;}//引用类型注入publicvoidsetNameDao(NameDaonameDao){this.nameDao=nameDao;}publicvoidsave(){System.out.println(this.name+"servicesave...");nameDao.getName();}}配置文件<!--管理对象--><beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"/><beanid="nameService"class="cn.bigdataboy.service.impl.NameServiceImpl"><!--引用类型写法--><propertyname="nameDao"ref="nameDao"/><!--简单类型写法--><propertyname="name"value="bigdataboy"/></bean>例子代码:https://pan.bigdataboy.cn/s/n8RFW构造器注入构造器的输入,不外乎需要注意参数是怎么注入的对象格式publicclassNameServiceImplimplementsNameService{publicNameDaonameDao;publicStringname;//常规写法publicNameServiceImpl(NameDaonameDao,Stringname){this.nameDao=nameDao;this.name=name;}publicvoidsave(){System.out.println(this.name+"servicesave...");nameDao.getName();}}配置文件构造器的注入,因为解耦,所以有几种写法<!--管理对象--><beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"/><beanid="nameService"class="cn.bigdataboy.service.impl.NameServiceImpl"><!--这里的name是参数名称,这样还是耦合,所以还有其他写法--><constructor-argname="nameDao"ref="nameDao"/><constructor-argname="name"value="bigdataboy"/><!--通过类型匹配--><!--<constructor-argtype="cn.bigdataboy.dao.NameDao"ref="nameDao"/>--><!--<constructor-argtype="java.lang.String"value="bigdataboy"/>--><!--通过索引(参数位置)--><!--<constructor-argindex="0"ref="nameDao"/>--><!--<constructor-argindex="1"value="bigdataboy"/>--></bean>例子代码:https://pan.bigdataboy.cn/s/XmVTK依赖自动装配要实现自动,那肯定是需要写法规范,不然框架也不知道你要怎么装自动装配是利用set方法实现的。自动装配只能对引用类型进行装配,不能对简单类型进行装配。自动和手动配置能搭配使用,自动装配的优先级小于手动。五种自动装配模式byName对象里的set方法的名字,需要与配置文件的Beanid相对应,不然会找不到。byType这个模式就不需要id和set对应了例子代码:https://pan.bigdataboy.cn/s/254HZ集合类型注入集合类型的注入只是在配置文件的写法有区别,会有多个原素对象的格式publicclassNameServiceImplimplementsNameService{privateint[]array;privateList<String>list;privateSet<String>set;privateMap<String,String>map;privatePropertiesproperties;publicvoidsetArray(int[]array){this.array=array;}publicvoidsetList(List<String>list){this.list=list;}publicvoidsetSet(Set<String>set){this.set=set;}publicvoidsetMap(Map<String,String>map){this.map=map;}publicvoidsetProperties(Propertiesproperties){this.properties=properties;}@Overridepublicvoidsave(){System.out.println("array:"+Arrays.toString(this.array));System.out.println("list:"+this.list);System.out.println("set:"+this.set);System.out.println("map:"+this.map);System.out.println("properties:"+this.properties);}}配置文件格式还是简单<beanid="nameService"class="cn.bigdataboy.service.impl.NameServiceImpl"><propertyname="array"><array><value>100</value><value>200</value></array></property><propertyname="list"><list><value>100</value><value>200</value></list></property><propertyname="set"><set><value>100</value><value>200</value></set></property><propertyname="map"><map><entrykey="name"value="bigdataboy"></entry></map></property><propertyname="properties"><props><!--这个有点特殊--><propkey="name">bigdataboy</prop></props></property></bean>例子代码:https://pan.bigdataboy.cn/s/Y4jSb

编程杂谈

新博客:https://blog.bigdataboy.cn/article/442.htmlBean基础配置格式<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--管理对象--><beanid="nameDao"name="daodao2,dao3"class="cn.bigdataboy.dao.impl.NameDaoImpl"/></beans>属性列表属性描述idBean唯一标识nameBean的别名,多个由逗号、分号隔开class该Bean的类路径scope作用范围,用于规定获取的Bean是否是单例的(默认是singleton单例)scope属性singleton单例:也就是使用的是同一个对象prototype非单例:常用于对象内部是有属性保存状态的,该对象运行一次,内部的属性需要给下次的执行。Bean实例化使用构造方法实例化Bean的实例化,也是从构造方法开始,容器内部是使用反射机制完成的<beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"scope="singleton"/>这里有个小问题,如果是非单例模式,会输出两次构造函数的打印使用工厂函数实例化需要继承FactoryBean,重写getObjectgetObjectType,isSingleton需要再写packagecn.bigdataboy.factory;importcn.bigdataboy.dao.NameDao;importcn.bigdataboy.dao.impl.NameDaoImpl;importorg.springframework.beans.factory.FactoryBean;publicclassNameDaoFactoryBeanimplementsFactoryBean<NameDao>{@OverridepublicNameDaogetObject()throwsException{returnnewNameDaoImpl();}@OverridepublicClass<?>getObjectType(){returnNameDaoImpl.class;}@OverridepublicbooleanisSingleton(){returntrue;}}配置文件只需要这样写<!--使用FactoryBean方式实例化Bean--><beanid="nameDao"class="cn.bigdataboy.factory.NameDaoFactoryBean"></bean>Bean生命周期生命周期其实很好理解,就是创建,销毁这样一个过程,既然有这样一个概念,那就可以控制相应阶段做不同的事。Spring的实现方式还是使用配置属性,指定相应方法初始化方法和销毁方法importcn.bigdataboy.dao.NameDao;importcn.bigdataboy.service.impl.NameServiceImpl;publicclassNameDaoImplimplementsNameDao{publicNameDaoImpl(){System.out.println("NameDaoImplconstructorrunning...");}publicvoidgetName(){System.out.println("getName:bigdataboy");}publicvoidinit(){//初始化方法System.out.println("namedaoinit...");}publicvoiddestory(){//销毁方法System.out.println("namedaodestory...");}}配置文件,指定相应方法<beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"init-method="init"destroy-method="destory"/>销毁方法,需要修改成ClassPathXmlApplicationContext接口才有,不然是不会调用销毁的。

编程杂谈

新博客:https://blog.bigdataboy.cn/article/441.htmlIoc/Ioc容器/DI需要解决的问题:解耦,不手动new对象,而是容器提供对象。使用new对象会产生高耦合,在改动代码后,必须重新编译、打包、部署Ioc(控制反转)使用对象时,有主动new产生对象转变成外部提供对象。Ioc容器外部提供对象的容器就叫Ioc容器,对象将由Ioc容器管理对象,能够管理对象的创建、初始化等一系列事情,创建后的对象被称为BeanDI(依赖注入)在容器中建立Bean与Bean之间的依赖关系,这个过程叫做依赖注入例子解决疑问:怎么实现的不用new:容器管理容器怎么知道管理什么对象:使用spring规定的xml配置文件DI怎么实现的依赖注入:配置项关联例子使用5.2.10.RELEASE版本<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency></dependencies>创建spring配置(需要加载maven依赖后,才会有这个选项)在spring配置配置文件中添加beanid:Bean的唯一标识name:Bean的别名,多个由空格逗号分割class:后面是需要容器管理对象的路径<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--管理对象--><beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"/></beans>使用,不用new体现在,使用nameDao对象不是new出来的packagecn.bigdataboy;importcn.bigdataboy.dao.NameDao;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassApp1{publicstaticvoidmain(String[]args){//传入配置文件路径不会这么使用,仅举例ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");//从容器获取对象NameDaonameDao=(NameDao)context.getBean("nameDao");nameDao.getName();}}业务层的处理需要依赖数据层的对象,需要使用DI处理它们的依赖配置添加属性标签并建立关联<!--管理对象--><beanid="nameDao"class="cn.bigdataboy.dao.impl.NameDaoImpl"/><beanid="NameService"class="cn.bigdataboy.service.impl.NameServiceImpl"><!--配置NameService类中依赖的beanname是NameServiceImpl类中的变量名,ref才是bean的id关联--><propertyname="nameDao"ref="nameDao"></property></bean>业务层的类也需要开启一个接口方法,方便容器进行设置publicclassNameServiceImplimplementsNameService{/***原来业务层需要new数据层进行操作*privateNameDaonameDao=newNameDaoImpl();*/privateNameDaonameDao;publicvoidsave(){System.out.println("nameservicesave...");nameDao.getName();}//相对于开个接口给容器,好能能进行设置publicvoidsetNameDao(NameDaonameDao){this.nameDao=nameDao;}}[]()相关代码:https://pan.bigdataboy.cn/s/bDrs0

编程杂谈

说明对JDBC进行简单的封装,方便使用完整代码:https://pan.bigdataboy.cn/#/s/nMC0数据库数据创表DROPTABLEIFEXISTSuser;CREATETABLEuser(idBIGINT(20)NOTNULLauto_incrementCOMMENT'主键ID',nameVARCHAR(30)NULLDEFAULTNULLCOMMENT'姓名',ageINT(11)NULLDEFAULTNULLCOMMENT'年龄',emailVARCHAR(50)NULLDEFAULTNULLCOMMENT'邮箱',PRIMARYKEY(id));加入数据INSERTINTOuser(id,name,age,email)VALUES(1,'Jone',18,'test1@bigdataboy.com'),(2,'Jack',20,'test2@bigdataboy.com'),(3,'Tom',28,'test3@bigdataboy.com'),(4,'Sandy',21,'test4@bigdataboy.com'),(5,'Billie',24,'test5@bigdataboy.com');构建目录工具类连接工具类,封装连接对象,方便获取连接packagecn.bigdataboy.util;importjava.sql.PreparedStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassDBConnectionUtil{//创建连接参数privatestaticStringdriver="com.mysql.jdbc.Driver";privatestaticStringurl="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";privatestaticStringusername="";privatestaticStringpassword="";//获取连接对象publicstaticConnectiongetConnection(){Connectionconn=null;//获取连接try{//加载驱动Class.forName(driver);conn=DriverManager.getConnection(url,username,password);}catch(SQLExceptionthrowables){throwables.printStackTrace();}catch(ClassNotFoundExceptione){e.printStackTrace();}returnconn;}//关闭全部publicstaticvoidcloseAll(ResultSetrs,PreparedStatementps,Connectionconn){if(rs!=null){try{rs.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}};if(ps!=null){try{ps.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}};if(conn!=null){try{conn.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}}}}测试连接工具类publicstaticvoidmain(String[]args){Connectionconnection=getConnection();System.out.println(connection);}用户实体类用户实体类的字段需要与数据表字段对应packagecn.bigdataboy.entity;publicclassUser{privateintid;privateStringname;privateintage;privateStringemail;publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.email=email;}}定义dao层接口dao层主要功能是提供对数据库数据的操作类packagecn.bigdataboy.dao;importcn.bigdataboy.entity.User;publicinterfaceUserDao{//通过id查询用户UsergetUserById(intid);}实现UserDao接口packagecn.bigdataboy.dao.impl;importcn.bigdataboy.dao.UserDao;importcn.bigdataboy.entity.User;importcn.bigdataboy.util.DBConnectionUtil;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassUserDaoImplimplementsUserDao{//通过id查询用户publicUsergetUserById(intid){Useruser=null;Connectionconn=null;PreparedStatementps=null;ResultSetrs=null;try{//通过连接工具类获取连接对象conn=DBConnectionUtil.getConnection();Stringsql="select*fromuserwhereid=?";ps=conn.prepareStatement(sql);ps.setInt(1,id);//设置第一个问号的值rs=ps.executeQuery();//执行SQL语句//判断是否返回到值,多个值需要循环使用next()获取if(rs.next()){//设置user值user=newUser();user.setId(rs.getInt("id"));user.setName(rs.getString("name"));user.setAge(rs.getInt("age"));user.setEmail(rs.getString("email"));}}catch(SQLExceptionthrowables){throwables.printStackTrace();}finally{//关闭全部DBConnectionUtil.closeAll(rs,ps,conn);}returnuser;}}测试实现的getUserById()方法packagecn.bigdataboy.dao;importcn.bigdataboy.dao.impl.UserDaoImpl;importcn.bigdataboy.entity.User;importorg.junit.Test;publicclassTestUserDaoImpl{@TestpublicvoidTestGetUserById(){intid=1;UserDaoImpluserDao=newUserDaoImpl();Useruser=userDao.getUserById(id);System.out.println(user.getId());System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getEmail());System.out.println(user.getClass());}}其他的修改、添加、删除数据都是一样的,完整代码里有

2020-10-17 703 0
编程杂谈

IO&NIO的区别NIOJavaNIO(NewIONonBlockingIO)是从Java1.4版本引入的一个新的IOAPI,可以替代标准的JavaIOAPI。NIO与原来的IO有着同样的作用和目的,但是使用的方式不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将更加高效的方式进行文件读写操作。区别IONIO面向流(Stream)面向缓冲区(Buffer)阻塞IO(BlockingIO)非阻塞IO(NonBlockingIO)无选择器(Selecors)缓冲区(Buffer)创建缓冲区(allocate)缓冲区本质就是数组,用于存储不同的数据缓冲区类型:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer//分配一个指定大小的Byte缓冲区(大小必须指定)ByteBufferbbuffer=ByteBuffer.allocate(1024);读&取缓冲区的两大核心方法缓冲区放入数据(put)放入方法put()有很多重载这里说明一下第一种:put(byte[]src,intoffset,intlength)byte[]src:放入缓冲区的数组intoffset:放入缓冲区数组的偏移量intlength:偏移量向后放入length位数据到缓冲区后两个参数为可选,不设置,表示把整个数组放入缓冲区。//Strings="abcde";byte[]bytes=newbyte[]{'a','b','c','e','f'};//数据放入缓冲区//bbuffer.put(s.getBytes());bbuffer.put(str.getBytes());读取缓冲区数据(get)在读取缓冲区数据之前,需要转换缓冲区模式为读取模式。bbuffer.flip();//读取缓冲区数据首先需要切换缓冲区模式System.out.println(bbuffer.get(0));//97打印出来的是字节码清空缓冲区但是'清空'后,缓冲区的数据依然存在,处于被遗忘状态bbuffer.clear();缓冲区的四大核心属性大小关系:mark<=position<=limit<=capacitycapacity:容量,代表缓冲区存储数据的大小,一旦声明不能改变limit:界限,表示缓冲区可以操作数据的大小(limit后的数据不能进行读写)position:位置,表示缓冲区正在操作数据的位置。mark:标记,表示记录当前position的位置,可以通过reset()恢复到mark位置。创建缓冲区时写入数据时读取数据时mark记录position的位置@Testpublicvoidtest(){byte[]bytes=newbyte[]{'a','b','c','e','f'};//创建放入数据切换模式ByteBufferbuf=ByteBuffer.allocate(10);buf.put(bytes);buf.flip();//记录position的位置buf.mark();//创建新的数组取出缓冲区的数据,添加到des字节数组byte[]des=newbyte[buf.limit()];buf.get(des,0,2);//输出数组的值System.out.println(newString(des,0,2));System.out.println(buf.position());buf.reset();//恢复position到mark位置System.out.println(buf.position());}

2019-10-28 1050 0