IOC:反转控制,反转资源获取。如:以前买菜(Bean)需要到菜市场,现在只需要在家门口放菜篮子,就有主动(Spring)动送菜来。
DI:依赖注入。
Spring的配置文件:applicatioContext.xml
<beans>
<!--配置一个bean说明-->
<!--
id:配置一个bean并赋值一个id,建议类名的第一个字母小写
class:需要配置的bean的全类名,因为要反射创建bean,Bean中需要有无参构造方法
-->
<bean id="" class="" >
<!--property,bean的属性注入,对应set方法-->
<property name="字段名" value="字段值"></property>
<!--属性引用其他Bean-->
<property name="字段名" ref="otherBeanId"></property>
<!--或引用内部Bean-->
<property name="字段名" ref="BeanName"></property>
<!--内部Bean,不能被外部引用-->
<property name="BeanName">
<bean class=""></bean>
</property>
<!--通过构造方法参数顺序来配置bean的属性
如果value有特殊字符,使用<![CDATA[vaule]]>包括起来
如果赋null值,使用<null/>
-->
<constructor-arg value="" index="" type=""></constructor-arg>
<!--或-->
<constructor-arg index="" type="">
<value><![CDATA[vaule]]></value>
</constructor-arg>
<constructor-arg index="" type="">
<value><null/></value>
</constructor-arg>
<!--为级联属性赋值-->
<constructor-arg ref="字段名"></constructor-arg>
<property name="字段名.属性" value=""></property>
<!--配置集合List属性-->
<property name="字段名">
<list>
<ref bean=""/>
<value></value>
</list>
</property>
<!--配置Map-->
<property name="字段名">
<map>
<entry key="" value-ref=""></entry>
</map>
</property>
<!--配置properties属性-->
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">root123456</prop>
</props>
</property>
</bean>
<!--配置单例的集合bean,供多个bean引用,需要导入uitl命名空间-->
<util.list id="cars">
<ref bean="car1"/>
<ref bean="car2"/>
</util.list>
<bean id="" class="">
<property name="list" ref="cars"></property>
</bean>
<!--使用p命名空间给bean的属性赋值-->
<bean id="" class="" p:属性1="" p:属性2=""></bean>
<!--
bean之间的关系
abstract="true" 可以添加成抽象bean,当作其他bean的模板使用,不能被实例化,
若某个bean的class没有被指定,则该bean必须是一个抽象bean
depends-on="car" 实例化一个bean的时候必须有Car属性,依赖于car
-->
<bean id="address1" class="Address" p:city="SZ" p:street="KeJiYuan" abstract="true"></bean>
<bean id="address2" p:city="SZ" p:street="KeJiYuan" abstract="true"></bean>
<bean id="address3" class="Address" p:street="BaoAn" parent="address1"></bean>
<bean id="address4" class="Address" p:street="NanShan" parent="address2"></bean>
<bean id="person" class="Person" p:name="Tom" p:address-ref="address2" depends-on="car"></bean>
<!--bean的作用域scope
prototype - 每次向IOC容器获取bean的时候都会生成一个新的bean
singleton - 在IOC容器中只有一个,每次获取的都是同一个bean,单例的
-->
<bean id="car" class="Car" scope="prototype"></bean>
<!--spring使用外部属性文件-->
<!--1、导入属性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--2、使用属性文件-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--使用外部属性文件-->
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" vaule="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<!--不适用外部属性文件
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
<property name="driverClass" vaule="com.mysql.jdbc,Driver"></property>
<property name="jdbcUrl" value="jdbc://mysql:///test"></property>
-->
</bean>
<!--Spring表达式语言 SpEL-->
<bean id="address" class="Address">
<property name="city" value="#{'Beijing'}"></property>
</bean>
<bean id="car" class="Car">
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI * 80}"><property>
</bean>
<bean id="person" class="Person">
<property name="car" value="#{car}"></property>
<property name="city" value="#{address.city}"></property>
<property name="info" value="#{car.price > 300000 ? '金领' : '白领'}"></property>
</bean>
<!--IOC容器中Bean的生命周期
car被初始化时调用car.init方法
car被销毁是调用car.destory方法
-->
<bean id="car" class="Car" init-method="init" destory-method="destory">
<property name="brand" value="Audi"></property>
</bean>
<!--bean的后置处理器
需要java实现
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
return null;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
return null;
}
}
bean的init方法调用之前之后会调用相应的方法
-->
<bean class="MyBeanPostProcessor"></bean>
<!--通过静态工厂方法配置bean
public class StaticFactory {
private static HashMap<String, Car> cars = new HashMap<>();
static {
cars.put("Audi",new Car());
cars.put("BMW",new Car());
}
public static Car getCar(String name) {
return cars.get(name);
}
}
-->
<bean id="car1" class="StaticFactory" factory-method="getCar">
<constructor-arg value="Audi"></constructor-arg>
</bean>
<!--通过FactoryBean配置Bean
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String brand;
public void setBrand(String brand){
this.brand = brand;
}
@Override
public Car getObject() throws Exception {
return new Car(brand);
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
-->
<bean id="car" class="CarFactoryBean">
<property name="brand" value="BMW"></property>
</bean>
</beans>
//1、创建SpringIOC容器对象ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicatioContext.xml");
//2、从IOC容器中获取bean对象
Bean bean = (Bean)ctx.getBean("beanId");
Bean bean = (Bean)ctx.getBean(Bean.class);//这种方式要求IOC中只有一个Bean