注入对象方式:
在xml配置文件中配置<bean>标签,bean标签id或name都可以标识这个bean对象,用id表示则这个对象对应的类只能出现一次,name表示对应类可以出现多次
1.set方式注入,配置标签,格式为:
<bean id="helloBean" class="ioc.HelloBean">
<property name="name">
<value>tom</value>
</property>
<property name="age" value="20">
</property>
</bean>
赋值时, 基本数据类型和String类型:用value赋值 集合数组类型:
数组:
<array>
<value>array1</value>
<value>array2</value>
</array>
list集合:
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
set集合:
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
map集合:
<map>
<entry key="key1">
<value>value1</value>
</entry>
<entry key="key2"
value="value2">
</entry>
<!-- 上面两种均可 -->
</map>
property集合:
<props>
<prop key="key1">prop1</prop>
<prop key="key2">prop2</prop>
</props>
类类型
用ref指向配置文件中的bean对象
对象类型的装配
1 用于涉及的对象的id在本配置文件中
.<ref local=" "/>
2 用于涉及的对象的id不在本配置文件中
<ref bean=" "/>
1.对象类型的装配可以使用自动注入
(当容器中有对应类型的对象时,容器自动找到对应的对象赋值)
1>在bean标签中指定配置方式 autowire=“byName” spring容器会到当前的类中找property的名字,然后再根据这个名字去spring容器中找有没有和这个property名字相同的对象,有就赋值,没有就不赋值 autowire=“byType”: spring容器会根据当前类中的set方法里面参数的类型,去容器中找相匹配的对象,如果没找到不赋值,如果找到一个就注入进来,如果找到多个,那么就会报错了. autowire=“constructor” 根据构造器的参数类型去匹配
2>在beans标签中配置装载方式default-autowire =“byName” 在根元素中加入这个属性,下面所有bean都会使用byName的方式进行自动注入,如果在下面的某一个bean想使用其他的方式进行注入,可以用autowire=""属性进行说明,或者某一个bean不想使用任何自动注入就使用autowire=“no”
2.构造器方式注入
配置<constructor_arg>标签,在bean类中不用写set方法,但要有相应的构造器 构造器注入有俩种形式 一个是根据参数类型 一个是根据参数位置的下标
3.配置文件中,一个bean的配置可以继承另一个bean的配置 bean标签中的俩个属性:
abstract属性 <bean name=".." class=".." abstract="true">
注:bean中一旦定义为了abstract=“true”,则说明当前配置是一个抽象配置,不能通过该bean获得对象,但可以再写一个配置去继承这个抽象的配置,当然即使当前这个配置不是抽象的,也能够被继承 parent属性,指定继承哪个bean的配置
<bean name=".." parent="另一个bean的名字">
xml文件中可以导入其他xml文件,在xml文件中配置<import>
标签,例:
<import resource="teacher.xml"/>
xml文件中配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:文件名.properties</value>
</property>
</bean>
这个配置可以自动读取对应properties文件中存放的key-value形式的数据,读完之后我们就可以用${key}这种形式去拿文件中的value值了
自定义属性编辑器PropertyEditor
String在注入时,如果遇到类型不一致(例如需要Address类型但是用户传了个String),此时就需要调用相应的属性编辑器进行转换(一般用户传的都是String字符串) 新建类继承PropertyEditorSupport,重写 getAsText() setAsText(String text) 方法,在setAsText方法中将用户传入的text处理成目标类对象并将目标类对象传入setValue(Object o) 在xml中配置
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="目标类全限定名" value="对应编辑器全限定名"/>
</map>
</property>
</bean>
这个配置指明哪个类型对应哪个自定义编辑器,当xml文件中出现给目标类对象传了一个String字符串,就会自动调用对应编辑器
写好配置文件后容器获得bean对象的使用方法:
1.反射调用
String[] path = {"ioc/applicationContext.xml","ioc/other.xml"};
ApplicationContext ac = new ClassPathXmlApplicationContext(path);
SomeBean sb = (SomeBean) ac.getBean("someBean");
通过上述语句得到在配置文件中配置好的对象
2.通过工厂类获得实例
新建一个类实现接口FactoryBean<目标类>,这个类就是工厂类,
这个类中要有目标类的所有属性,对应get/set
然后实现这个接口中的三个抽象方法:
getObject()
isSingleton()
getObjectType()
在xml配置文件中配置好工厂类后,
在main方法中通过反射工厂类就可以得到目标类对象
3.通过实例工厂获得bean对象(不需要实现或者继承任何接口或者父类),
就是一个普通的类(工厂类),要获得哪个对应类对象,就将这个类对象的所有属性加到工厂类,增加get/set方法,在工厂类中写 get目标类 方法,返回值为目标类对象
在xml文件中配置工厂类、再配置:
<bean name="conn" factory-bean="factory" factory-method="get目标类"></bean>
在main方法中通过getBean(“conn”);就可以得到目标类对象
4.通过静态工厂获得实例
生成一个普通类,要获得哪个对应类对象,就将这个类对象的所有属性加到工厂类,设为静态并赋值,增加静态方法 get目标类 ,返回值为目标类对象
在xml文件中配置:
<bean name="conn" class="工厂类全限定名" factory-method=" get目标类 "></bean>
在main方法中通过getBean(“conn”);就可以得到目标类对象
自定义事件
写一个类继承ApplicationEvent,则这个类就是事件类,
监听器类:
写一个类实现ApplicationListener<目标事件类>接口,并重写onApplicationEvent(当前类对象)
当main调用container.publishEvent(当前事件类对象)时,就会触发监听这个事件的监听器并调用监听器类的onApplicationEvent(当前类对象)方法
注解:
配置bean
@Component注解可以直接定义bean,而无需在xml定义。但是若两种定义同时存在,xml中的定义会覆盖类中注解的Bean定义
使用时需要在xml中配置<context:component-scan/>
标签,默认自动扫名指定路径下的包(含所有子包)
spring检查指定包下的java类,看它们是否使用了 @Component注解需要配置:
<context:component-scan base-package="指定包名" />
component-scan标签包含了annotation-config标签的作用,也就是说配置了自动注入功能
1)@Component注解直接写在类上面
2)@Component有一个可选的参数,用于指定bean的名称 @Component(“name”),如果不指定参数,则bean的名称为当前类的类名小写,如果指定参数,则bean的名称为指定参数
3) @Component 定义的bean默认情况下都是单例模式的,如果要让这个bean变为非单例,可以再结合这个 @Scope注解来达到目标 @Scope(“prototype”)
4) @Component是Spring中所有bean组件的通用形式, @Repository @Service @Controller 则是 @Component的细化,用来表示更具体的用例,分别对应了持久化层、服务层和表现层。但是至少到现在为止这个四种注解的实质区别很小(甚至几乎没有),都是把当前类注册为spring容器中的一个bean component-scan标签将带有 @Component @Repository @Service @Controller注解的类自动注册到spring容器中
5)component-scan标签对标记了 @Required @Autowired @PostConstruct @PreDestroy @Resource @WebServiceRef @EJB @PersistenceContext @PersistenceUnit 等注解的类进行对应的操作,使注解生效
实现自动注入:
@Autowired 和 @Resource实现自动注入
1)需要在xml文件中配置: <context:annotation-config/>
标签
2)可以写在成员变量、setter方法、构造器函数上面
3)@Autowired默认按照byType匹配的方式进行注入,如果没有一个bean的类型是匹配的则会抛异常,如果有多个bean的类型都匹配成功了,那么再按byName方式进行选择
@Resource是默认先用byName,如果找不到合适的就再用byType来注入
4) @Autowired如果最终匹配不成功(注意一定是一个都没有找到的情况)则会抛出异常,但是如果设置为 @Autowired(required=false),则最终匹配不成功没有不会抛出异常。
5) @Autowired可以结合 @Qualifier(“beanName”)来使用,则可以达到byName的效果
6) @Resource有俩个属性,name和type,使用name属性则表示要byName匹配,使用type属性则表示要byType匹配