[TOC]
控制反转IOC就是对象创建的由谁来控制。
Student.stu = new Student( ); ===>程序员创建对象
stu.setName("张三"); ===>程序员进行赋值
stu.setAge(18);
<bean id="stu" class="com.achong.entity.Student"> ===>Spring容器负责对象的创建
<property name="name" value="张三"> ===>Spring容器依赖注入值,也就是对对象赋值
<property name="age" value="20">
</bean>
Bean管理是指两个操作:Spring创建对象 和 Spring给对象的属性注入值。
Bean管理有两种实现方式:基于XML配置文件 和 基于注解 。
Spring提供IOC容器实现的两种方式:BeanFactory和ApplicationContext
IOC容器的基本实现,是Spring内部使用的接口,一般不提供开发人员使用。
BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员使用。
方式一:创建对象并注入值
Bean标签是创建对象
propertory标签是为对象的属性注入值。若不需要注入则该标签不用写。
注意:创建对象是调用无参构造方法,注入值是使用set方法。所以必须保证对象类里有这两种方法。
<!--创建学生对象,在容器启动的时候-->
<bean id="stu" class="com.achong.entity.Student">
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
</bean>
取出对象
ClassPathXmlApplicationContext( )方法读取xml配置文件。
getBean( )方法取出创建好的对象。参数名为xml里对应Bean标签的id。
@Test
public void TestSpringStudent(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student) ac.getBean("stu");
System.out.println(stu );
}
方式二:创建对象并注入值
此方式调用的是带参的构造方法创建对象。
使用 构造方法 的 参数名称 注入值。
<bean id="school" class="com.achong.entity.School">
<constructor-arg name="name" value="广东工程职业技术学院"></constructor-arg>
<constructor-arg name="address" value="广东省清远市清城区"></constructor-arg>
</bean>
使用 构造方法 的 下标 注入值。
<bean id="stu" class="com.achong.entity3.Student">
<constructor-arg index="0" value="2005"></constructor-arg>
<constructor-arg index="1" value="achong"></constructor-arg>
<constructor-arg index="2" value="18"></constructor-arg>
<constructor-arg index="3" ref="school"></constructor-arg>
</bean>
使用 构造方法 的 参数 的 顺序 注入值。
<bean id="stu" class="com.achong.entity4.Student">
<constructor-arg value="2005"></constructor-arg>
<constructor-arg value="achong"></constructor-arg>
<constructor-arg value="18"></constructor-arg>
<constructor-arg ref="school"></constructor-arg>
</bean>
简单类型指的是八大基本数据类型。使用value属性注入。上面的例子就是简单类型注入。
引用类型指的是另一个对象。使用ref属性注入。
集合类型注入指数组,List,Map。
例如User类里包含另一个Address类。这时候就需要引用类型注入。
代码实现 - 引用类型注入
<!-- 创建学校对象-->
<bean id="school" class="com.achong.entity2.School">
<property name="name" value="广东工程职业技术学院"></property>
<property name="address" value="广东省清远市清城区中宿路"></property>
</bean>
<!-- 创建学生对象-->
<bean id="stu" class="com.achong.entity2.Student">
<property name="name" value="achong"></property>
<property name="age" value="20"></property>
<property name="school" ref="school"></property>
</bean>
代码实现 - 集合类型注入
<bean id="stu" class="com.achong.entity.Student">
<!--数组类型-->
<property name="courses">
<array>
<value>java</value>
<value>Mysql</value>
</array>
</property>
<!--List类型注入-->
<property name="maps">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
<!--Map类型注入-->
<property name="sets">
<set>
<value>Mysql</value>
<value>Redis</value>
</set>
</property>
</bean>
添加util约束空间,把list提取出来。提取出来的集合独立,可供多个Bean使用。
<util:list id="bookList">
<value>java</value>
<value>Mysql</value>
<value>Servlet</value>
</util:list>
<bean id="stu" class="com.achong.entity5.Student">
<property name="courseList" ref="bookList"></property>
</bean>
内部Bean写法
<bean id="stu" class="com.achong.entity2.Student">
<property name="name" value="achong"></property>
<property name="age" value="20"></property>
<property name="school">
<bean id="school" class="com.achong.entity2.School">
<property name="name" value="广东工程职业技术学院"></property>
<property name="address" value="广东省清远市"></property>
</bean>
</property>
</bean>
空值
<property name="address">
<null/>
</property>
特殊符号
第二个中括号里面的内容为输入值。
<property name="address">
<vlaue><[!CDATA[<<广东省>>]]></vlaue>
</property>
也称为DI(Dependency Injection),它是IOC的具体实现的技术。
使用注解管理bean,可以省去在xml配置文件里写很多行代码,为xml减负。
四个注解的功能一模一样,可以混用,但是不建议,因为这本来就是用来区分三层结构的,value也可以不写,不写的话,创建的对象的名字按照驼峰命名法来命名。
值类型的注入
引用类型的注入
只扫描指定包。指定包下面的,带有指定注解的类将被创建。
<context:component-scan base-package="com.achong.entity"></context:component-scan>
创建对象并注入
@Component
public class Student {
@Value("2005")
private int id;
@Value("achong")
private String name;
@Value("18")
private int age;
@Autowired
private School school;
}
添加测试类测试
@Test
public void Test01(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student) ac.getBean("student");
System.out.println(stu);
}
注意:在有父子类的情况下,使用按类型注入,就意味着有多个可注入的对象,此时按照名称进行二次筛选,选中与被注入对象相同名称的对象进行注入。
所以,如果有父子类,建议使用按名称注入。
批量包扫描, 逗号隔开
<context:component-scan base-package="com.achong.entity , com.achong.entity2 , com.achong.entity3"></context:component-scan>
自定义包扫描规则
<!--
use-default-filters 表示不使用默认扫描规则
include-filter 设置扫描哪些内容,这里表示 只扫描Controller这个注解
-->
<context:component-scan base-package="com.achong" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--
exclude-filter 设置哪些内容不扫描,这里表示Controller这个注解不会被扫描
-->
<context:component-scan base-package="com.achong">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
上面的方法需要使用到xml配置文件。但是,使用配置类可以替代配置文件。
步骤:
创建一个空白类,添加相应注解
@Configuration //标记为配置类,替代xml文件
@ComponentScan(basePackages = {"com.achong.entity4"}) //扫描路径
public class SpringConfig {
}
注意:原本的
new AnnotationConfigApplicationContext(SpringConfig.class)
应改成
new AnnotationConfigApplicationContext(SpringConfig.class);
@Test
public void Test04(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
Student student = (Student) ac.getBean("student");
System.out.println(student);
}
评论 (0)