idea创建父子工程:
1.创建一个maven工程
2.删掉maven工程下的src文件
3.邮件maven工程,新建一个modul,勾选archetype,选择webapp,不断next
4.子工程的pom文件,加入spring依赖,引入spring依赖。新建src文件,src下面新建main文件夹。
5.刷新maven,会自动刷新为一个web工程,src-main下自动多出一个webapp文件夹,webapp下面会自动多出jsp文件,WEB-INF文件。pom文件里面会多出build等其他配置。
6.在main下面新建java和resource,标记为资源文件。最终如下:
7.在resource下面创建spring.xml文件。
如果没有spring Config文件,刷新一下maven,如果还是没有则单独打开子工程就有了。刷新maven主要是为了刷新一下spring-content依赖。
1.javaconfig
2.xml
2-1.set方法+property标签来注入。
例如:setDao,spring会把set去掉,把D转小写,去寻找dao,找到了就set进去。而不是按照属性名来找的。
2-2.构造函数+construct标签。
也可以注入一些固定的数据结构【但是这个一般不会用】
<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setAdminEmails(java.util.Properties) call --> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean>
2-3.引入命名空间
就是可以吧propert简写成p:xxx,construct简写成c:xxx。
从sprig的官方文档中,我们可以看出来,上面这两个东西并不需要引入xsd文件(xsd文件是用来做代码提示的),spring把这两个xsd文件定义到内核里面了,所以我们直接用即可。
【注意】:如果你注入类里面写了构造方法,那么只能用constructor方法来注入。或者用c:xxx。否则会失败不出的。
2-4.xml文件之自动装配
自动装配的前提是要ioc里面有对应的实现类 => 这里先复习一下之前的注入策略。
自动装配的话,思路就是把所有的类都以bean的方式写入到xml文件中。然后我们自己的类定义好对应的属性即可。
2-4-1.byName注入
byName注入的话,需要提供set方法。具体的操作原理其实就是,去掉set,把第一个字母小写,最后找到id,注入。假如是setDao=>寻找id为dao的类。
2-4-2.byType注入
byType注入的话,跟之前一样,如果一个接口有2个实现类A和B。类A写在xml里面
,然后注入的话用接口来注入,那么会注入类A,也就是类A。
3.注解
3-1.和xml文件配合
xml文件开启注扫描和扫描指定的包即可把对应的类注入到ioc中,xml文件能引用到ioc里面的类,也就是所谓的混搭使用。
后面的话,只需要这一句:
<context:component-scan base-package="com"></context:component-scan>
只需要在xml里面指定一下扫描,其他的类使用注解来注入即可
3-2.单纯注解
通过配置一个注解类,直接读取这个注解类,触发其他类的扫描。
4.强强联合
通过读取一个javaconfig类,读取到对应的包,加载额外的xml文件,注入ioc,可以实现注解+xml+javaconfig。
5.其他注解
@Compoment是@service、@controller、@Repository的父类。只不过其他三个比较特定。一般建议使用@Component,因为@Component后面可能会有其他的用途,未来spring很有可能会取消component原有的功能。
5-1.@Autowired
按type来注入,而且仅只能按照type来注入,如果一个接口有多个实现类,那么需要使用其他注解来辅助注入。
如果autowired找不到对应的类,那么他会按照属性名去ioc容器里面寻找。举个例子,
有两个类A和B,实现了接口C。然后A和B都用service来注入,然后分别提供了dao1和dao2的name,然后提供一个类D,D使用@autowired注入一个类型为接口C的属性,属性名为dao1.这个时候,注入的是类A。
说明按找type来注入,找不到的话,会按照属性名来找,为什么只能通过属性名?因为autowirede不能提供name,所以没办法只能去属性名啦。
5-2.@Resource
啥都不指定的时候,默认按属性名来注入。如果按属性名找不到,则按照type来注入。resource也可以指定对应的类型来注入。当使用resource指定name和type的话,就是指定了一个唯一bean了。
【注意】autowired和resource正好相反
6.自定义bean名称
为什么对象要交给spring管理 =》 spring能够提供丰富的功能,包括给你这个类加个aop代理,然后还能用事务之类的功能,可以扩展非常多的功能。
7.Bean的作用域
1.单例
single
2.多例
property
3.作用域注入的原理
假设A依赖了B,B是A里面的一个属性。首先实例化B,然后把B注入到A里面,最后执行A的构造方法。因为A是单例的,所以A只会被实例化一次,A实例化一次,那么A的依赖自然也就会只注入一次,在这个情况下,如果B是多例的,那么B会变相变成单例,因为A只依赖了B一次。由此引出下面这个问题:"在一个单例中引用了一个多例的bug"
3.在一个单例中引用了一个多例的bug
3-1.实现一个接口
这种方式和spring的耦合度过高,不推荐
3-2.使用注解
值得注意的是,其中的LookUp指定的name,是其他bean注入的name