第一篇:关于JAVA一些问题 程序总结
关于JAVA一些问题 程序总结
public interface SinterFace { public final static String intstr=“hello is interface”;public abstract void nostat();}
public class Useinter implements SinterFace {
int inter = 5;static String str = “hello is class”;public double dou = 1.0;
public void nostat(){ System.out.println(“is no static method”);}
public static void stat(){ System.out.println(“is static method”);} }
public class Main {
public static void main(String[] args){
System.out.println(“静态变量方法在类实例化之前都可以调用:”);Useinter.stat();System.out.println(Useinter.str +“n”);
System.out.println(“非静态变量方法要在类实例化之后才可以调用:”);Useinter useinter = new Useinter();useinter.nostat();System.out.println(useinter.dou);System.out.println(“类中没声明是private的变量默认都是public”);System.out.println(useinter.inter);
System.out.println(“n类里的静态变量可以被实例调用:”);System.out.println(useinter.str +“n”);
System.out.println(“接口里的静态变量可以直接被调用:”);System.out.println(SinterFace.intstr);} }
第二篇:java程序转exe过程总结
首先要下载三个东西。Fat Jar插件、exe4j 软件、Inno Setup软件
下载地址:sourceforge.net/projects/fjep/files/ 点击“Download net.sf.fjep.fatjar_0.0.31.zip(246.3 kB)”即可下载。(1)Fat Jar : Eclipse可以安装一个叫Fat Jar的插件,用这个插件打包非常方便,可以直接将JAVA项目打包成可执行JAR包。
1.下载后的文件如下图所示。
2.打开下载会的ZIP包,将里面的Jar解压到Eclipse安装路径下的plugins文件夹中。
3.如果Eclipse已经启动需要重启一下,没有启动直接打开Eclipse即可。
4.打开Eclipse之后,右击要打开的工程,出现一个“Build Fat Jar”,点击它。
5.如果没有出现它,可以选择“Export”,从弹出的对话框中选择“other”-->“Fat Jar Exporter”,点击Next,选择要打包的项目,再点击Next。
6.出现如下图这样的窗口。选中Use extern jar-name,这样能将生成的Jar保存到工程外的路径。
7.选择Main-Class,点击Browse找到可运行的主类。
8.选择one-jar,点击Accept。
9.点击Next进入下一步,出现下面的界面,直接点击Finish即可。
打包完成,点击OK即可。去刚刚指定的位置找到Jar,双击即可运行。(com.simontuffs.onejar.Boot 就是你的入口程序,下面转成exe时会用到)
(2)exe4j 软件+ Inno Setup软件
对于作Java桌面应用来说,比较烦人的就是安装部署问题,客户端是否安装有jre、jre版本问 题、jre去哪下载、如何用jre启动你的Java应用?不要说刚接触电脑的人,就算是比较熟悉电脑,如果没有接触过Java,面对一个Java应用,如何在Windows下启动它,估计都会折腾半天。
最好的方式莫过于带着JRE,让用户轻松点击就能运行。带着JRE运行,JRE的大小应该是最让 人头疼的,我默认安装的jre6大小达到80M,而程序只有200-300k左右,感觉非常不合理,分发与 网络传输过程也会大受影响!因此针对自己程序精简jre非常必要,关于jre的精简问题请参考其他 文章,本文在此不做说明。
针对windows平台,让用户一键式安装,双击使用,使用工具exe4j+InnoSetup,这两个工具都 可以在网上找到,下面通过一个实例进行说明。
第一步:将自己的java程序打包成“可执行的jar包”,可以采用eclipse等IDE工具打包。下面 以eclipse为例进行说明:
上面截图应该注意的是:第一步是要求你选择你的java程序的引导类,下面是输出路径,类文 件的处理上我们选择第二种,即将该java程序所需的jar包一起打包进来,最后点击finish。完成后 最好双击一下导出的可执行jar包,确保可正确运行。
第二步:准备打包文件夹。
1.在任意路径下新建文件夹,文件夹的命名可以使用项目的名字,如此例的项目名takephoto。将在第一步中生成的jar包复制进来。
2.将精简以后的jre文件包复制进来,如果尚不掌握精简方法,可以暂时采用安装的庞大jre,如
下图:
将上图的jre复制进去即可。
3.在takephoto文件夹下新建lib文件夹,将项目所需的jar包,如数据库驱动等复制进去。4.可以在准备一个ico文件夹,存放一个或几个ico图标或图片。经以上几步后,文件结构应该是:
第三步:使用exe4j工具生成exe文件:
直接下一步,这一步
要求选择类型,我们选择第一个,这样可以保证程序仍具有跨平台的特性。如果选择第二个,可以 把程序完全编译成exe文件,可以更好的保护你的程序不被反编译。
上面是设置你的程序的短文件名,源文件夹路径(如我的:E:takephoto),以及要生成的exe文件的存 放目录,exe存放目录必须指定到源文件夹下,这里我把它指定为E:takephoto的根目录下。
上面是给我们即将生成的exe文件起一个名字,如我的“takephoto”,还可以给它指定一个ico类型的 图标,其它按默认就可以了,在指定ico图标路径的时候建议采用绝对路径,因为在测试的时候发现
如果采用相对路径在生成exe文件的时候提示出错,且经测试采用绝对路径也能保证程序的准确性。
上面是要求把程序中所用到的类路径添加上去。然后指定程序的启动类,其它如果没有必要的话,则按默认即可,点击+号添加类路径,注意,要首先添加类路径再指定启动类,类路径包含两部分,一是我们在第一步生成的可执行jar包,二是程序所需的其他jar包路径,即lib文件夹路径。如图:
上面是把生成的可执行jar包路径添加进去了,下面添加lib文件夹路径。注意,全部采用相对路径 如.takephoto.jar,.lib。
在添加lib文件夹
路径的时候选择scandirectory。
上面是
把lib文件夹路径添加进去了。下面就可以指定启动类了。
先选择我们的程序所需要的jre版本,然后便是选择我们自带的jre了,这一步不是必须,但是为了更好的分发程序,我们自带了jre,所以必须把我们自带的jre指定为首选的运行环境,如图选择:接下来
Searchsequence
默认情况下程序会去系统的注册表,环境变量及相关的目录查找jre,因为我们只需要自带的jre,所以 这里我把默认的选项移除了,然后添加我们自己的jre所在的目录路径,点+号开始:
均采用默认即可:
下面的
上面的
可以添加一个启动画面,如指定一个gif图片。
好了exe
文件已经生成完毕了。点击exit退出即可,退出时提示配置已经改变是否保存,可以保存,保存后 为takephoto.exe4j,下次可以直接双击这个文件进行编辑我们上面的配置。经过以上操作,文件夹结构变为:
双击一下takephoto.exe也可以执行了。
第三步:利用InnoSetup工具进行压缩打包,做成安装程序。
可以采用家脚本向导,也可以将上面画面关掉,直接“文件-新建”即可。
上面是设置一些信息,比如程序名称,版本信息,发布者,应用程序官方网站。
这一步点击浏览选择主执行文件即我们第二步生成的exe执行文件:
下一步是添加文件夹:
点击是即可 菜单文件夹名称,根据需求进行勾选。下面的一直点击下一步即可
上面是指定开始
上面可以自定义输出文件夹,生成的安装包文件名默认是setup,自定义安装程序图标,安装密码。
本名称。点击保存之后立即进行如下编译:
指定脚
编译完成之后,文件的默认输出位置在源文件夹下的程序自动创建output文件夹中。最终文件夹的结构是:
以上便是我们需要的安装程序。值此全部结束,如有错误敬请指正!
2011年3月25日星期五22:11:25
注意:
(1)生成的exe程序如果发生如下错误:
可用下面的方法解决:
exe4j是个很好的打包利器,官方下载地址:http://www.xiexiebang.com/download/exe4j/files.php
如果你不注册,打包好的软件每次启动都会报:this executable was created with an evaluation version of exe4j,特烦人,所以最好下载exe4j的破解版,但是有注册码,官方软件毕竟比破解版好用,下面的注册码经测试,均可以使用.用户名和公司名可随便填 A-XVK258563F-1p4lv7mg7sav
A-XVK209982F-1y0i3h4ywx2h1
A-XVK267351F-dpurrhnyarva
A-XVK204432F-1kkoilo1jy2h3r
A-XVK246130F-1l7msieqiwqnq A-XVK249554F-pllh351kcke50
A-XVK238729F-25yn13iea25i
A-XVK222711F-134h5ta8yxbm0
A-XVK275016F-15wjjcbn4tpj
A-XVK275016F-15wjjcbn4tpj
(2)你的 Java 应用程序的运行类(这里写你 java 程序的入口类,为了避免错误,可以 用好压打开你的 jar 文件,找到 META-INF 中的 MANIFEST.MF 件,并用记事本打 开,Main-Class: com.simontuffs.onejar.Boot 中的 com.simontuffs.onejar.Boot 就是你 的入口程序,如果直接用 java 程序的主类可以会出错,在用 fatjar 插件打包后,我们 的 编 写 的 程 序 被 两 次 打 包,以 至 于 入 口 类 发 生 了 变 化,上 面 的 com.simontuffs.onejar.Boot 就是用 fatjar 插件打包时自动生成的入口类)
第三篇:java 问题汇总(总结,重点)
在用到spring框架中时,场景如下
post 请求过去,对象接收不到参数的值(解决办法:考虑到在参数上加个@RequestBody 注解即可,有些没加的是框架帮忙处理了后默认接收的是json串)http://localhost:8080/xxxxxxxxxxx-xxxxxxx-api/xxxxxx/xxxxx/xxxxxxxxx/suggest/add.sgt
======================================== mapper.xml->@Repository{存储数据层}->@Service{业务层}->@Controller{展示层}(spring注解可以理解为这样的线性,任其项目结构怎么变这样的线性结构是不会变的,万变不离其宗)
@Repository @Service @Controller均是注册在spring上下文中 @Autowired 在spring上下文中找bean
@Qualifier 配合 @Autowired使用 当找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier(“beanName”),明确指定bean的名称进行注入 @RequestMapping 配置连接
@Required 注册在sett方法上,检查有没有被调用 @RequestParam 绑定参数
@RequestBody读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上
如果你也用过struts2.简单介绍下springMVC和struts2的区别有哪些? springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。2.Spring的事务是如何配置的?
先配置事务管理器TransactionManager,不同的框架有不同属性。再配置事务通知和属性,通过tx:advice。配置,设置那些方法或者类需要加入事务。
3.spring事务控制放在service层,在service方法中一个方法调用service中的另一个方法,默认开启几个事务?
spring的事务传播方式默认是PROPAGATION_REQUIRED,判断当前是否已开启一个新事务,有则加入当前事务,否则新开一个事务(如果没有就开启一个新事务),所以答案是开启了一个事务。4.spring 什么情况下进行事务回滚?
Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚
unchecked异常,即运行时异常runntimeException 回滚事务;checked异常,即Exception可try{}捕获的不会回滚.当然也可配置spring参数让其回滚.spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。5.Spring支持的事务管理类型? Spring支持两种类型的事务管理:
编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
6.Spring框架的事务管理有哪些优点?
它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如 它支持声明式事务管理。
它和Spring各种数据访问抽象层很好得集成。7.讲下Spring的七大事务传播?
Spring中通过Propagation来设置事务的传播属性的,在这个属性中提供了我们其中关于事务传播的特性:
PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。
8.事务并发会引起什么问题,怎么解决?
事务并发会引起脏读,幻读,不可重复读等问题,设定事务的隔离级别就可以解决。
9.事务的安全问题:锁机制的实现原理及在项目中的使用?
锁有悲观锁和乐观锁,悲观锁一般假设每个人都会修改数据,默认情况下把数据都锁住,影响性能,但安全性高.乐观锁是假设每个人都只读下数据,不会修改数据,性能比较高,但是安全性较低,一般通过增加类似于版本控制里面版本号来解决问题。10.讲下BeanFactory和ApplicationContext的区别?
BeanFactory是Spring容器顶级核心接口,比较早,但功能比较少,getBean就是BeanFactory定义的。
ApplicationContext是Spring里面的另外一个容器顶级接口,它继承于BeanFactory,但是提供的功能譬如校验,国际化,监听,对Bean的管理功能比较多,一般使用ApplicationContext。11.简单介绍下你对mybatis的理解? mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。12.讲下MyBatis和Hibernate的区别? MyBatis是JDBC的轻量级封装,把Sql和java代码独立出来,性能相对比较高,写SQL语句相对于比较灵活,并且容易调试,一般用在大型项目中.Hibernate是JDBC的重量级封装,开发速度比较快,但是性能比较低,调试不方便,一般适合对进度要求的比较高的中小型项目.13.mybatis中#{}和${}的区别是什么?
${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值,比如ps.setInt(0, parameterValue),#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值,相当于param.getItem().getName()。14.mybatis中XML映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?、、、、,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。15.MyBatis编程步骤是什么样的? 创建SqlSessionFactory 通过SqlSessionFactory创建SqlSession 通过sqlsession执行数据库操作 调用session.commit()提交事务 调用session.close()关闭会话
16.JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
① 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。②Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
③向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决: Mybatis自动将java对象映射至sql语句。
④对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。解决:Mybatis自动将sql执行结果映射至java对象。17.使用MyBatis的mapper接口调用时有哪些要求? Mapper接口方法名和mapper.xml中定义的每个sql的id相同
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml文件中的namespace即是mapper接口的类路径。18.简单的说一下MyBatis的一级缓存和二级缓存?
Mybatis首先去缓存中查询结果集,如果没有则查询数据库,如果有则从缓存取出返回结果集就不走数据库。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象 Mybatis的二级缓存即查询缓存,它的作用域是一个mapper的namespace,即在同一个namespace中查询sql可以从缓存中获取数据。二级缓存是可以跨SqlSession的。
19.Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
20.Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复? 不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;毕竟namespace不是必须的,只是最佳实践而已。
原因就是namespace+id是作为Map的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。21.为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。22.SSM优缺点、使用场景?
1.Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
2.Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。3.Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
4.总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。23.SpringMvc里面拦截器是怎么实现的?
有两种方式,一种是实现接口,另外一种是继承适配器类,然后在SpringMvc的配置文件中配置拦截器即可:
24.Spring中AOP的应用场景、Aop原理、好处?
AOP--Aspect Oriented Programming面向切面编程;用来封装横切关注点,具体可以在下面的场景中使用: Authentication 权限、Caching 缓存、Context passing 内容传递、Error handling 错误处理Lazy loading懒加载、Debugging调试、logging, tracing, profiling and monitoring 记录跟踪优化 校准、Performance optimization 性能优化、Persistence 持久化、Resource pooling 资源池、Synchronization 同步、Transactions 事务
原理:AOP是面向切面编程,是通过动态代理的方式为程序添加统一功能,集中解决一些公共问题。优点:
1.各个步骤之间的良好隔离性耦合性大大降低
2.源代码无关性,再扩展功能的同时不对源码进行修改操作。
第四篇:JAVA实习生问题
JAVA实习生问题:
1.我班只招三人。2.实习从现在开始,至于结束,暂时没有时间限制,因为公司项目较多,缺乏人手,项目周期长。听他们说他们现在接了一个安徽省的云平台项目,这个就够他们忙的了。如果最后你们能够成长起来,并且愿意留下来,他们也很高兴,也就相当于培养自己的员工。
3.工作内容:项目组带着做项目。相当于一边学习一边动手做。所以兴趣很重要,如果很有兴趣,具有一定的分析问题解决问题的能力,遇到问题,则是自己积极想办法解决,而且觉得很有成就感,在有兴趣的前提下,跟着项目组做项目也是学的最快的;但是如果兴趣并不是很大,那么就变成了压力、痛苦和无聊。
4.此次公司招实习生,对基础没什么要求(只要学过java就行),重要的是兴趣。如果动手能力、自学能力较强,具有较强的分析问题、解决问题的能力,即使基础不是很好,也应该问题不大。有兴趣,遇到问题就不会觉得难,而是自己积极的想办法去解决。
5.对于女生来说,需要考虑的更多一些,比如安全问题,毕竟是在校外实习。这些问题你们自己要考虑到,也都是要让你们自己负责的。要慎重,自己考虑清楚。
6.公司招实习生的目的是帮着项目组做项目。不是很想干的,最好别去。
7.工作有两个方向,软件开发or系统集成,方向自己选,看你们对哪一块感兴趣。如果基础好一点,项目组就带着你们做;如果基础薄弱,不光带着做,还会有培训。实际上带着做项目,是学的最快的,但是前提是有兴趣。至于具体做什么,要看是什么项目,是项目中的哪一部分。
第五篇:Java面试问题
1、引用CSS样式有哪两种方式?
Link,@import2、js怎么控制两个文本框,当选中的时候边框变空,没选中的变会原来的颜色。onFocus=“document.getElementById('text1').style.backgroundColor='#eee'”
onblur=“document.getElementById('text1').style.backgroundColor='#fff'”
3、查询数据库表显示在页面需要新建多少个class文件和xml文件?
4、spring有多少种注入方式?
注入方法1:构造方法方式 2:属性注入 3:静态工厂方法参数注入 4: 接口注入