//1.创建对象
HelloWorld helloWorld=new HelloWorld();
//2.给属性赋值
helloWorld.setName("lc");
*/
//以上两步可通过spring来完成
//1.创建spring的IOC容器对象
//ApplicationContext 代表IOC容器,是一个接口
//ClassPathXmlApplicationContext 是ApplicationContext的实现类
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从IOC容器中获取Bean实例
//利用id准确定位到IOC容器中获取Bean实例
HelloWorld helloWorld= (HelloWorld) ctx.getBean("helloworld");
在spring项目的src下创建xml配置文件,而在spring中配置bean有以下方法:
一.class:bean的全类名,通过反射的方式在IOC容器中创建Bean,
所以要求Bean中必须有无参的构造器
id:标识容器中的bean,id要求唯一
<bean id="helloworld" class="com.itlc.spring.bean.HelloWorld">
<!--利用setter方法对属性进行注入,是开发中最常用的注入-->
<property name="name" value="lc">
<!--属性值也可以通过value标签子节点进行配置
如果字面值包含特殊符号可以通过<![CDATA[特殊字面值]]>
<value><![CDATA[<lc>~]]></value>-->
</property>
</bean>
二.使用构造器注入属性值,index属性标识对应构造方法中的顺序,无index默认为按序注入。
type标识数据类型,用于区分多个具有相同数量参数的构造器
<bean id="car" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="300000.0011"/>
</bean>
car的构造方法
public Car(String name, Double price) {
this.name = name;
this.price = price;
}
三.当配置对象拥有内部对象时
1.可以使用ref通过id来使对象之间建立关系
<bean id="person" class="com.itlc.spring.bean.Person">
<property name="age" value="20"></property>
<property name="name" value="xdy"></property>
<property name="car" ref="car">
<!--
也类似value可以通过标签子节点进行配置
<ref bean="car"></ref>
-->
</property>
<!--为级联属性赋值-->
<property name="car.maxSpeed" value="500"></property>
</bean>
2.可以通过内部bean进行配置
<bean id="person1" class="com.itlc.spring.bean.Person">
<property name="age" value="20"></property>
<property name="name" value="xdy1"></property>
<property name="car">
<bean class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="300000.0011"/>
</bean>
</property>
</bean>
四.配置集合属性
<bean id="rich" class="com.itlc.spring.bean.RichPeople">
<constructor-arg index="0" value="xgr"/>
<constructor-arg index="1" value="20"/>
<constructor-arg index="2">
<!--配置集合属性可利用标签list,set,map来进行,
集合中元素利用ref配置好的bean建立关系,或者使用内部bean-->
<list>
<!--利用id建立关系-->
<ref bean="car1"></ref>
<ref bean="car2"></ref>
<ref bean="car3"></ref>
<!--内部bean-->
<bean class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="baoshijie"/>
<constructor-arg index="1" type="int" value="500"/>
</bean>
</list>
</constructor-arg>
<constructor-arg index="3">
<map>
<!--利用id建立关系-->
<entry key="mother" value-ref="mother"></entry>
<!--内部bean-->
<entry key="father">
<bean id="father" class="com.itlc.spring.bean.Person">
<constructor-arg index="0" type="java.lang.String" value="x"/>
<constructor-arg index="1" type="int" value="40"/>
<constructor-arg index="2" ref="car"></constructor-arg>
</bean>
</entry>
</map>
</constructor-arg>
</bean>
RichPeople构造方法
ublic RichPeople(String name, int age, List<Car> car, Map<String,Person> family) {
this.name = name;
this.age = age;
this.cars = car;
this.family=family;
}
五.配置properties属性值,properties是map的子类
<bean id="datasource" class="com.itlc.spring.bean.DataSource">
<property name="properties">
<!--使用它props和prop来为properties属性赋值-->
<props>
<prop key="user">root</prop>
<prop key="password">root</prop>
<prop key="jdbcUrl">jdbc:mysql:///test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
六.配置单例的集合bean,供多个其他bean使用,需要在beans标签中导入
xmlns:util="http://www.springframework.org/schema/util"
<util:list id="cars">
<ref bean="car1"></ref>
<ref bean="car2"></ref>
<ref bean="car3"></ref>
</util:list>
<util:map id="family">
<entry key="father" value-ref="father"></entry>
<entry key="mother" value-ref="mother"></entry>
</util:map>
配置时,直接利用id进行连接即可
<bean id="rich1" class="com.itlc.spring.bean.RichPeople">
<constructor-arg index="0" value="xgr"/>
<constructor-arg index="1" value="20"/>
<constructor-arg index="2" ref="cars"></constructor-arg>
<constructor-arg index="3" ref="family"></constructor-arg>
</bean>
七.通过p命名空间进行赋值,需要先导入p命名空间
导入方法:在beans标签里面加
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person3" class="com.itlc.spring.bean.Person" p:age="20" p:name="xgg"
p:car-ref="car">
</bean>
<bean id="rich2" class="com.itlc.spring.bean.RichPeople" p:age="20" p:name="xgg"
p:car-ref="cars" p:family-ref="family">
</bean>
八.自动装配
使用autowrite进行自动装配,常用byName,自动匹配名字(匹配原则通过bean的id与
类的属性名进行联系,对应属性名必须具有set方法,若无匹配则为空;
第二个就是byType,自动匹配数据类型来进行装配,具有多个bean类型一致都可匹配时报异常
缺点:会自动装配所有属性,不可byName,byType同时使用,不够灵活
用于自动装配的bean:
<bean id="car" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="100000.0011"/>
</bean>
<bean id="car1" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="100000.0011"/>
</bean>
<bean id="car2" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="bengchi"/>
<constructor-arg index="1" type="int" value="500"/>
</bean>
<bean id="car3" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="baoma"/>
<constructor-arg index="1" type="int" value="500"/>
</bean>
<bean id="mother" class="com.itlc.spring.bean.Person">
<constructor-arg index="0" type="java.lang.String" value="g"/>
<constructor-arg index="1" type="int" value="40"/>
<constructor-arg index="2" ref="car"></constructor-arg>
</bean>
<bean id="father" class="com.itlc.spring.bean.Person">
<constructor-arg index="0" type="java.lang.String" value="x"/>
<constructor-arg index="1" type="int" value="40"/>
<constructor-arg index="2" ref="car"></constructor-arg>
</bean>
<util:list id="cars">
<ref bean="car1"></ref>
<ref bean="car2"></ref>
<ref bean="car3"></ref>
</util:list>
<util:map id="family">
<entry key="father" value-ref="father"></entry>
<entry key="mother" value-ref="mother"></entry>
</util:map>
自动装配:
<bean id="rich" class="com.itlc.spring.bean.RichPeople" p:age="20" p:name="xg"
autowire="byName">
</bean>
九.bean的继承,继承bean的其他属性
<bean id="parent" class="com.itlc.spring.bean.relation.Address" p:city="chengdu" p:street="chunxilu"></bean>
<bean id="son" p:street="xindudadao" parent="parent"></bean>
十.bean的抽象,将abstract属性赋值为true,则该bean不能被实例化,只能被用来继承
<bean id="abstract" class="com.itlc.spring.bean.relation.Address" p:city="chengdu"
p:street="chunxilu" abstract="true">
</bean>
若某个bean没有class属性,则该bean只能是抽象bean
<bean id="abstract1" abstract="true">
</bean>
十一.依赖关系,当bean中配置的对象必须依赖某个属性时使用depends-on指示依赖的bean,依赖的bean必须存在
<bean id="car" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="100000.0011"/>
</bean>
<bean id="person" class="com.itlc.spring.bean.Person"
p:car-ref="car" p:age="20" p:name="xggg" depends-on="car"></bean>
十二.bean的scope
bean的scope控制bean的生成
singleton:初始化时就生成一个对象,每次返回都返回这一个对象,单例的
prototype:原型的,初始化时不生成对象,每次返回时创建生成一个返回
<bean id="car" class="com.itlc.spring.bean.Car">
<constructor-arg index="0" type="java.lang.String" value="linkeng"/>
<constructor-arg index="1" type="java.lang.Double" value="100000.0011"/>
</bean>
<bean id="person" class="com.itlc.spring.bean.Person" scope="prototype"
p:car-ref="car" p:age="20" p:name="xggg" depends-on="car"></bean>
十三.外部属性文件
<!--1.导入属性文件-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--使用外部文件进行配置-->
<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
</bean>
外部配置文件:
user=root
password=root
jdbcUrl=jdbc:mysql:///test"
driverClass=com.mysql.jdbc.Driver"
十四.管理bean的生命周期
实现BeanPostProcessor接口,并具体提供
Object postProcessBeforeInitialization(Object bean, String beanName):init-method之前被调用
Object postProcessAfterInitialization(Object bean, String beanName):init-method之后被调用的实现
bean:bean实例本身
beanName:IOC容器配置的bean的名字
返回值:是实际上返回给用户的那个bean,注意:可以在以上两个方法中修改返回的bean,甚至返回一个新的bean
public class BeanProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println(o+"init"+s);
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println(o+"destroy"+s);
return o;
}
}
<!--配置bean的后置处理器:不需要配置id,IOC容器自动识别-->
<bean class="com.itlc.spring.bean.cycle.BeanProcess"></bean>
配置处理器以后的执行顺序:
1.构造器创建bean实例
2.调用后置处理器的postProcessBeforeInitialization方法
3.调用bean的初始化方法,init-method
4.调用后置处理器的postProcessAfterInitialization方法
5.使用bean
6.容器关闭时,销毁bean
十五.通过静态工厂方法来配置bean
注意:不是配置静态工厂方法实例,而是配置bean实例
<!--
class 属性:指向静态工厂的全类名
factory-method:指向静态工厂方法的名字
constructor-arg:如果工厂方法需要参数,则使用constructor-arg来配置参数
-->
<bean id="car" class="com.itlc.spring.bean.factory.StaticCarFactory" factory-method="getCar">
<constructor-arg value="audi"/>
</bean>
静态工厂类:
/*
静态工厂方法:直接调用某一个类的静态方法就可以返回Bean的实例
* */
public class StaticCarFactory {
private static Map<String,Car> cars = new HashMap<String,Car>();
static {
cars.put("audi",new Car("audi",300));
cars.put("ford",new Car("ford",400));
}
public static Car getCar(String name){
return cars.get(name);
}
}
十六.实例工厂方法配置bean
注意:需要先创建工厂本身,在调用工厂的实例方法来返回bean的实例
工厂类:
public class InstanceFactory {
private Map<String,Car> cars=null;
public InstanceFactory(){
cars=new HashMap<String,Car>();
cars.put("audi",new Car("audi",300));
cars.put("ford",new Car("ford",300));
}
public Car getCar(String brand){
return cars.get(brand);
}
}
配置文件:
<!--配置工厂的实例-->
<bean id="carFactory" class="com.itlc.spring.bean.factory.InstanceFactory"></bean>
<!--通过实例工厂来配置bean-->
<bean id="car0" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="ford"/>
</bean>
十七:通过注解配置
<!--
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
-->
<!--指定spring IOC容器扫描的包-->
<context:component-scan base-package="com.itlc.spring.bean.annotation"></context:component-scan>
<!--
可以通过resource-pattern="包名/*.class指定扫描的资源"
<context:component-scan base-package="com.itlc.spring.bean.annotation"
resource-pattern="repository/*.class"></context:component-scan>
-->
<!--
context:exclude-filter:子节点指定排除那些指定表达式的组件
<context:component-scan base-package="com.itlc.spring.bean.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:exclude-filter>
</context:component-scan>
-->
<!--
context:include-filter:子节点指定包含那些指定表达式的组件
在context:component-scan设置属性use-default-filters="false"表示只扫描include包含的包
<context:component-scan base-package="com.itlc.spring.bean.annotation">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:include-filter>
</context:component-scan>
-->
<!--
type属性若为annotation,则只包含加了注解的类,若为assinable,则包含了起继承和衍生出去的类
-->
十八.1.泛型依赖注入, 父类之间的关系,会被子类所继承
父类:public class BaseRepository<T> {}
public class BaseService<T> {
@Autowired
protected BaseRepository<T> repository;
public void add(){
System.out.println("Add...");
System.out.println(repository);
}
}
User:public class User {}
子类:
@Repository
public class UserRepository extends BaseRepository<User>{
}
@Service
public class UserService extends BaseService<User>{
}
xml:
<context:component-scan base-package="com.itlc.spring.bean.generic.di"></context:component-scan>
Main:
public class Main {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans-generic-di.xml");
UserService userService= (UserService) ctx.getBean("userService");
userService.add();
}
}
打印结果:
Add...
com.itlc.spring.bean.generic.di.UserRepository@47db50c5