1 Spring成功启动的三个条件
a 框架的jar包都放在了项目类路径下
b 应用程序为spring配置好所有bean配置信息
c bean的类都已经放到应用程序的类路径下
spring容器启动时,会读取bean配置信息,并在spring容器中生成bean配置注册表,然后根据注册表实例化bean,装配好bean的依赖关系
2 XML配置详解
2.1 Bean基本配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 对象的配置 -->
<bean id="user" class="a_hello.User"></bean>
</beans>
1 id是容器中Bean的名字,id必须以字母开始,命名要符合XML规范,如果想命名bean的名字以特殊字符如? #开头,可以用name属性
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 对象的配置 -->
<bean name="#user,$123" class="a_hello.User"></bean>
</beans>
2 id和name都可以写多个名字,spring不允许两个id名字相同,但可以两个name相同,这时通过getBean(beanName)获得的Bean是在最后面配置的bean对象,所以在配置bean的时候尽量用id来配置
3 如果id和name都没有配置,spring将类的全限定名作为bean的名字
3 spring依赖注入的方式
3.1 属性注入
3.2 构造函数注入
3.3工厂方法注入
3.1 属性注入
实现要求;有一个默认无参构造函数(不用敲代码,每个类默认有一个无参构造函数)、提供一个setter方法注入属性值或依赖对象
依赖注入的过程:spring先通过无参构造函数实例化Bean,通过反射的方式调用setter方法注入属性值
注意:默认构造函数是无参构造函数,Java语言规定,在类中如果没有显示定义任何构造函数,JVM会自动生成一个默认无参构造函数,反之,如果一个类中定义了一个带参构造函数如public Car(String brand),JVM就不会再生成无参构造,必须手动写一个无参构造public Car(),否则使用属性注入时会抛出异常
JavaBean属性命名的特殊规范:属性变量名以小写字母开头,但也可以大写,但必须满足变量的前两个字母要么全部大写,要么全小写
3.2 构造函数注入
3.2.1按参数的类型匹配入参
实现要求:Bean中提供一个带参构造函数
3.2.2按索引匹配入参
如果构造函数的参数的类型相同如两个都是string,仅仅通过指定类型就无法确定对应关系,这时需要添加索引
3.2.3联合使用类型和索引匹配、
注意:对于因参数数目相同类型不同引起的潜在配置歧义问题,spring容器可以正确启动且不会报错,它会随机匹配一个构造函数实例化bean,但随机可能不是正确的
属性值包含特殊字符如何处理?
XML的五个特殊字符:&<>"',解决办法 1 使用<![CDATA[这里写属性值]]>
2 将特殊字符用转义字符表示
XML会忽略元素标签内部字符串中的空格,但spring不会忽略,会把空格赋值给bean
集合配置
Properties
4 自动装配
springIOC了解容器中所有bean的配置信息,此外通过Java反射机制还可以获知实现类的结构信息(构造函数的结构、属性),这样可以实现自动装配,简化开发
共有四种自动装配类型:byName byType constructor autodetect
<!-- 根据“名称”自动装配: userAction注入的属性,会去ioc容器中自动查找与属性同名的对象 -->
<bean id="userAction"
class="cn.itcast.d_auto.UserAction" autowire="byName"></bean>
也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”,但是定义在beans上的装配类型会被bean上的装配类型覆盖,如果在beans上配置了全局,又在bean上配置了,会以bean上配置的为准
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName"> 根据名称自动装配(全局)
<!-- ###############自动装配############### -->
<bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>
<bean id="userService" class="cn.itcast.d_auto.UserService"></bean>
<bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean>
</beans>
5 方法注入
5.1 lookup:为一个单例的类注入多例 的bean,如Boss类是单例的,希望为Boss注入多例的Car属性,每次调用Boss的getCar()时,都能获得一个新的car,注意项目中要添加CGLIB包
6 bean之间的关系
继承 依赖 引用
6.1 继承:如果多个bean有相同的配置,可以把相同的部分,提出来成为一个单独的bean,其他的bean,来继承它,然后其他bean里配置自己不同的属性值
父bean里的abstract=true,表示不会被实例化成一个bean
6.2依赖:如果项目中,有一些初始化参数,这些参数在类中的系统配置文件中,配置文件中的数值是从数据库中读取的,那么每次系统启动时,要保证一些配置文件(如读取数据库中一些系统配置的值)首先被加载和实例化,然后一些配置才能被加载,这是就可以用depend-on标签来控制,配置文件被加载的顺序
7 bean的作用域
低版本只有2个作用域:singleton prototype
在spring2.0 中针对webapplicationcontext添加了3个作用域
7.1 singleton:默认配置,bean默认是单例,spring的ApplicationContext容器启动时,自动实例化所有singleton的bean并缓存于容器中,虽然启动费时一些,但有2个好处
1提前实例化会发现一些潜在的配置错误
2 以缓存的方式保存,运行时用到了bean就不用实例化了,提高运行效率
如果你不想提前实例化singleton的bean,可以用lazy-init来进行控制,但有时可能还会提前实例化,如果该bean被需要提前实例化的bean引用的话
7.2 prototype:默认情况,spring容器在启动时不实例化prototype的bean,此外spring容器将prototype的bean交给调用者后,就不在管理它的生命周期了
7.3
8 基于注解的配置
8.1
@Component
@Service:对Service实现类标注
@Controller:对Controller实现类标注
@Repository:对DAO实现类标注
如何使用注解:在配置文件头部引入context命名空间,使用 <context:component-scan base-package="">来扫描配置了注解的包下的类,如果只希望扫描特定包下的类使用resource-pattern
8.2 自动装配Bean
8.2.1 使用@Autowired进行自动注入:默认按照类型匹配注入,在容器中查找匹配的bean,当有且仅有一个匹配的bean时,spring将其注入到标注@Autowired的变量中
@Autowired的required属性
当没有一个匹配的bean时,spring会抛出NosuchBeanDefinitionException异常,如果希望没有找到bean不报错,就使用@Autowired(required=false),默认情况下required=true,即没有找到时抛出异常
使用@Qualifier指定注入Bean的名称
如果容器中有多个匹配的bean时,用@Qualifier限定bean的名称