IOC和DI
ioc:其思想是反转资源的获取方向。传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源,而拥有了ioc之和,则是容器主动的将资源推送给它所管理的组件,组件所需要做的仅仅是选择合适的方式接受资源,这种行为也被称为查找的被动形式
di:IOC的另一种表述方式:即组件以一些定义好的方式(如set方法)接受来自容器的资源注入,相对于ioc而言,这种表述更直接
applicationContext;在初始化上下文时就实例化所有的单例的Bean(调用无参构造器)。
ioc容器创建对象
1.<property>标签和<constructor>标签
<bean id="user" class="com.buka.edu.bean.User">
<!-- id 指的是调用user类里面的setId(){}方法,与方法名字有关,与属性字母大小写不影响-->
<property name="Id1" value="1"></property>
<property name="Name" value="李小胡"></property>
<!-- 构造器注入 默认情况下是按照构造器参数的顺序来的 index指的是下标 name指定的是参数名称-->
<constructor-arg value="123" name="name" index="1"></constructor-arg>
<constructor-arg value="1" name="id" index="0"></constructor-arg>
</bean>
2.当类属性包含类对象时
<!--方式一:ref--> <bean id="car" class="com.buka.edu.bean.Car"> <property name="brand" value="aodi"></property> <property name="price" value="10000"></property> </bean> <bean id="user1" class="com.buka.edu.bean.User"> <property name="id1" value="2"></property> <property name="name" value="李星龙"></property> <property name="car" ref="car"></property> </bean> <!-- 方式二:内部bean在property中使用 --> <bean id="user1" class="com.buka.edu.bean.User"> <property name="id1" value="2"></property> <property name="name" value="李星龙"></property> <property name="car"> <bean class="com.buka.edu.bean.Car"> <property name="price" value="2002"></property> <property name="brand" value="benchi"></property> </bean> </property> </bean> <!--方式三 :内部bean在constructor使用 ,在user类里创建个user的构造函数 --> <bean id="user1" class="com.buka.edu.bean.User"> <property name="id1" value="2"></property> <property name="name" value="李星龙"></property> <constructor-arg name="car" > <bean class="com.buka.edu.bean.Car"> <property name="price" value="2002"></property> <property name="brand" value="benchi"></property> </bean> </constructor-arg> </bean> <!--方式四: 级联属性赋值--> <bean id="user1" class="com.buka.edu.bean.User"> <property name="id1" value="2"></property> <property name="name" value="李星龙"></property> <property name="car.brand" value="???"></property> <property name="car.price" value="10000"></property> </bean> <!-- 给car赋值为null--> <bean id="user1" class="com.buka.edu.bean.User"> <property name="id1" value="2"></property> <property name="name" value="李星龙"></property> <property name="car"> <null/> </property> </bean> </beans>
3.集合创建(数组也是一样)
<!--方式一:内部标签list--> <bean id="person" class="com.buka.edu.bean.Person"> <property name="name" value="tom"></property> <property name="list"> <!--内部的集合list标签,也可以使用bean标签--> <list> <value>as</value> <value>bc</value> </list> </property> </bean> <!-- 方式二:通过ref--> <bean id="person1" class="com.buka.edu.bean.Person"> <property name="list" ref="list"></property> <property name="set" ref="set"></property> <property name="map" ref="map"></property> </bean> <util:list id="list"> <value>a</value> <value>b</value> <value>c</value> </util:list> <!--person对象集合--> <util:list id="list2"> <ref bean="person"></ref> </util:list> <util:set id="set"> <value>a</value> <value>b</value> <value>c</value> </util:set> <util:map id="map"> <entry key="a" value="12"></entry> <entry key="b" value="1"></entry> <entry key="v" value="12d"></entry> </util:map>
4. p标签:是<property>标签的简化
使用时要导入依赖
xmlns:p="http://www.springframework.org/schema/p"
<bean id="user" class="com.buka.edu.bean.User" p:name="tom" p:id1="1"></bean>
5.自动装配
自动装配:ioc容器中类型唯一的时候可以 一旦有多个相同类型时就不可以了 方式一: 通过类型自动装配指的是ioc容器当中 有和当前这个bean的属性相同类型的时候 会直接把那个bean注入到 当前这个bean
<bean id="ccaa" class="com.buka.edu.bean.Car">
<property name="price" value="11111"></property>
</bean>
<bean id="user2" class="com.buka.edu.bean.User" autowire="byType">//User类中存在car属性
</bean>
方式二:通过name来自动注入 bean的属性名和 ioc容器中的id名相同时 自动注入进来
<bean id="car" class="com.buka.edu.bean.Car">
<property name="price" value="11111"></property>
</bean>
<bean id="user3" class="com.buka.edu.bean.User" autowire="byName"></bean>
6.继承类
<!-- 父bean-->
<bean id="user" class="com.buka.edu.bean.User" p:name="tom" p:id1="1" abstract="true">
<!-- abstract为true时不允许被实例化,继承他的可以实例化。-->
</bean>
<!--
写一个bean继承id=user class 属性也能继承过来
也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类,
而共享相同的属性配置. 但此时 abstract 必须设为 true
-->
<bean id="user2" class="com.buka.edu.bean.User" parent="user"></bean>
7.依赖
Spring 允许用户通过 depends-on 属性设定 Bean 前置依赖的Bean,前置依赖的 Bean 会在本 Bean 实例化之前创建好 如果前置依赖于多个 Bean,则可以通过逗号,空格或的方式配置 Bean 的名称
<bean id="user" class="com.buka.edu.bean.User" depends-on="car">
</bean>
<bean id="car" class="com.buka.edu.bean.Car">
</bean>
<!-- prototype 不是单例的 默认是singleton 是单例的,就是可以创建多个对象 --> <bean id="user" class="com.buka.edu.bean.User" scope="singleton"></bean>
8.配置数据库的bean
第一步:导入连接池依赖和数据库依赖,写配置文件信息
第二步:在springxml文件导入配置文件
代码如下:
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
第三步:写dateSource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="username" value="${db.username}"></property> <property name="url" value="${db.url}"></property> <property name="password" value="${db.password}"></property> <property name="driverClassName" value="${db.driver}"></property> </bean>
9. 通过工厂获取bean对象
静态工厂:创建一个工厂,在工厂里创建对象,通过调用方法创建某个对象
代码如下
bean
<!-- 我们要car对象 class属性值 不能是car这个类了 应该是 能够生产这个car的 工厂类-->
<bean id="car" class="com.buka.edu.bean.FactoryTest" factory-method="getCar">
<!-- 通过构造方法传值-->
<constructor-arg value="200000"></constructor-arg>
<constructor-arg value="Audi"></constructor-arg>
</bean>
工厂类
package com.buka.edu.bean;
public class FactoryTest {
Car car;
public FactoryTest() {
}
public static Car getCar(double s, String s2)
{
return new Car(s,s2);
}
}
实例工厂:先创建工厂,再创建对象
核心标签:
factory-bean="工厂名字" factory-method="调用的方法", class="com.buka.edu.bean.Car"//创建的是哪个对象
代码如下:
<bean id="factoryTest1" class="com.buka.edu.bean.FactoryTest1"></bean>
<bean id="car" class="com.buka.edu.bean.Car" factory-bean="factoryTest1" factory-method="factoryCar">
<constructor-arg value="dsf"></constructor-arg>
</bean>
工厂类:
public class FactoryTest1 {
public Car factoryCar(String s) {
Car car=new Car();
car.setBrand(s);
return car;
}
}
spring注解
1.在spring配置文件中配置注解
自动扫描指定包以及子包下所有添加了注解的类 然后加入到ioc容器当中
assignable只扫描某个类
annotation只扫描某个注解
排除组件也是如此
<context:component-scan base-package="com.buka.edu.Spring">
<!-- 只包含的时候我们需要改变他的扫描规则-->
<!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<context:include-filter type="assignable" expression="com.buka.edu.Spring.controller.UserController"/>
</context:component-scan>
<!-- 排除组件-->
<context:component-scan base-package="com.buka.edu.Spring">
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
<context:exclude-filter type="assignable" expression="com.buka.edu.Spring.Service.UserService"/>
</context:component-scan>
2.在各种层类上面写注解
注解的分类
- @Component : 组件,没有明确的角色(实体类)
- @Service : 在业务逻辑层(service层)使用
- @Repository : 在数据访问层(dao层)使用.
- @Controller : 在展现层(MVC--SpringMVC)使用
但是作用都是相同的:把注解下面的类对象交给ioc容器管理
3.如何从ioc获取这些类对象
@Autowired
上图: