IOC:
IOC操作:Bean管理
什么是Bean管理
Bean管理就是两个操作:
(1)Spring创建对象
(2)Spring注入属性
Bean管理操作的两种方式:
1.xml配置文件方式
(1)创建对象
<bean id="user" class="com.User.User"> </bean>
(2)注入属性
1.使用set方法注入
(1).创建类,定义属性和对应的set方法
(2)在Spring配置文件中先进行配置对象创建,配置属性注入
<!--set方法注入属性-->
<bean id="n" class="com.User.User">
<!--在property中完成属性注入-->
<property name="name" value="大黄"/>
</bean>
2.使用有参构造进行注入
(1)创建类,定义属性,创建属性对应有参构造方法
(2)在Spring配置文件中先进行配置
<!--有参构造创建对象-->
<bean id="student" class="com.User.Student">
<!--在constructor-arg中完成属性注入-->
<constructor-arg name="name" value="红红火火"/>
<constructor-arg name="age" value="15"/>
</bean>
3.特殊(null,特殊符号等)
<!--有参构造创建对象-->
<bean id="student" class="com.User.Student">
<!--在constructor-arg中完成属性注入-->
<constructor-arg name="name" value="红红火火"/>
<constructor-arg name="age" value="15"/>
<!--将address设置为null-->
<property name="address">
<null/>
</property>
</bean>
4.注入属性-外部bean
UserDao:
public interface UserDao {
public void update();
}
UserService:
public class UserService {
//1.创建UserDao类型的属性,生成set方法
private UserDao userDao;
//2.生成set方法后,就可以调用
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(){
System.out.println("service add...");
userDao.update();
}
}
Spring配置文件:
<bean id="service" class="com.Service.UserService">
<!--注入UserDao对象
name:类里面属性名
ref:创建userDao对象bean标签id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.Service.UserDaoImpl"></bean>
5.注入属性-内部bean
以上边的为例:
```xml
<bean id="service" class="com.Service.UserService">
<!--注入UserDao对象
name:类里面属性名
ref:创建userDao对象bean标签id值
-->
<!-- <property name="userDao" ref="userDaoImpl"></property>-->
<property name="userDao">
<bean id="userDaoImpl" class="com.Service.UserDaoImpl">
<!--在这里可以用property注入值-->
</bean>
</property>
</bean>
6.级联赋值
<bean id="service" class="com.Service.UserService">
<!--级联赋值-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.Service.UserDaoImpl"></bean>
7.xml注入集合属性;
数组类型
List集合
Map集合
Set集合
<bean id="stu" class="com.jihe.Stu">
<!-- 数组类型属性注入-->
<property name="courses" >
<array>
<value>Spring</value>
<value>java</value>
<value>mysql</value>
</array>
</property>
<!-- List类型属性注入-->
<property name="list">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
<value>d</value>
</list>
</property>
<!-- map类型属性注入-->
<property name="map">
<map>
<entry key="1" value="数组"/>
<entry key="2" value="集合"/>
<entry key="3" value="面向对象"/>
</map>
</property>
<!-- set类型属性注入-->
<property name="set">
<value>set1</value>
<value>set2</value>
</property>
</bean>
在集合中设置对象类型
<!-- 注入list集合类型,值是对象-->
<property name="courseList">
<list>
<bean id="c1" class="com.jihe.Course">
<property name="cname" value="Spring"/>
</bean>
<bean id="c2" class="com.jihe.Course">
<property name="cname" value="MyBatis"/>
</bean>
</list>
</property>
把集合注入部分提取出来
前提:添加了util约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
<!-- 使用util完成提取list类型属性注入-->
<util:list id="booklist">
<value>java</value>
<value>mysql</value>
<value>jsp</value>
<value>css</value>
</util:list>
<!-- 2.提取list集合注入使用-->
<bean id="book" class="com.jihe.Book">
<property name="list" ref="booklist"></property>
</bean>
Spring中有两种类型的bean,一种是普通bean,另外一种是工厂bean(FactoryBean)
1.普通bean:配置文件中定义的bean类型就是返回类型(xml中的class中的文件就是 测试类中getBean的类型)
2.工厂bean:配置文件中定义的bean类型可以和返回类型不一样
Bean的作用域
在Spring中创建bean实例默认为单实例(创建两个对象,地址是相同的),可以设置为多实例
默认:
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean-jihe.xml");
Book book1 = (Book) context.getBean("book");
Book book2 = (Book) context.getBean("book");
System.out.println(book1==book2);
book1.test();
}
在xml中可以在bean标签中的scope属性进行设置:
scope属性值:1.默认 singleton(表示单实例对象)
2.prototype(表示多实例对象)
<bean id="book" class="com.jihe.Book" scope="prototype">
singleton和prototype的区别:
1.singleton是单实例,prototype是多实例
2.(创建时机不同)当scope的值为singleton的时候,在加载spring配置文件时就会创建单实例对象,将scope的值设置为prototype的时候,不是在加载spring配置文件的时候创建对象,而是在调用getBean方法的时候创建多实例对象
Bean生命周期
1.通过构造器创建bean实例(无参数构造)
2.为bean的属性设置值和对其他bean引用(调用set方法)
3.调用bena的初始化方法(需要进行配置初始化的方法)
4.bean可以使用了(对象已经获取)
5.当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
演示代码:
package com.jihe;
public class smzq {
private String name;
public smzq() {
System.out.println("第一步 执行无参数构造创建bean实例");
}
public void setName(String name) {
this.name = name;
System.out.println("第二步,调用set方法设置属性值");
}
@Override
public String toString() {
return "smzq{" +
"name='" + name + '\'' +
'}';
}
//创建执行的初始化方法
public void initMethod(){
System.out.println("第三步,执行初始化方法");
}
//创建执行的销毁方方法
public void destroyMethod(){
System.out.println("第五步,执行销毁方法");
}
}
<bean id="sm" class="com.jihe.smzq" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="生命周期"/>
</bean>
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean-jihe.xml");
smzq sm = (smzq) context.getBean("sm");
System.out.println("第四步 获取创建bean实例对象");
System.out.println(sm);
//手动让bean实例销毁
((ClassPathXmlApplicationContext)context).close();
}
添加后置处理器之后:
在配置文件中添加后置处理器之后,会自动地为配置文件中的所有bean实例都添加上后置处理器
1.通过构造器创建bean实例(无参数构造)
2.为bean的属性设置值和对其他bean引用(调用set方法)
把bean实例传递bean后置处理器的方法 (postProcessBeforeInitialization)
3.调用bena的初始化方法(需要进行配置初始化的方法)
把bean实例传递bean后置处理器的方法 (postProcessAfterInitialization)
4.bean可以使用了(对象已经获取)
5.当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
自动装配
<!-- 自动装配:autowire
byName:根据属性名称注入,bean的id值和类中属性名称必须相同
byType:根据属性类型注入,如果有多个相同类型bean的时候会出错
-->
<bean id="emp" class="com.Auto.Emp" autowire="byName">
<!-- <property name="dept" ref="dept"></property>-->
</bean>
<bean id="dept" class="com.Auto.Dept"></bean>
直接配置数据库信息
(1)将druid使用Maven进行配置
(2):
<!--直接配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url"
value="jdbc:mysql://localhost:3306/userDb"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties 格式文件,写数据库信息
(2)把外部 properties 属性文件引入到 spring 配置文件中
- 引入 context 名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
在 spring 配置文件使用标签引入外部属性文件
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${prop.driverClass}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.userName}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
IOC操作Bean管理(基于注解方式)
Spring针对Bean管理中创建对象提供注解:
1.@Component
2.@Service
3.@Controller
4.@Repository
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--开启组件扫描
1.如果要扫描多个包,可以使用逗号隔开
2.扫描包得上层目录
-->
<!-- <context:component-scan base-package="com.zhujie"></context:component-scan>-->
<!--
use-default-filters="false"表示现在不使用默认filter,而是使用自己配置得
context:include-filter 设置需要扫描那些内容 type表示扫描的类型(是注解,还是别的)
expression="org.springframework.stereotype.Component表示只会扫描zhujie文件下带Component注解的类
-->
<context:component-scan base-package="com.zhujie" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>
<!--
没有使用flase,表示扫描所有,然后加限制条件
context:exclude-filter 设置不去扫描那些内容-->
<!-- <context:component-scan base-package="com.zhujie" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>-->
</beans>
属性注入:
1.@Autowired:根据属性类型进行自动装配
2.@Qualitier:根据属性名称进行注入 需要和Autowired一起使用
3.@Resource:可以根据类型注入,可以根据名称注入
UserDao:
public interface UserDao {
public void add();
}
UserDaoImpl:
@Repository(value="userDaoImpl1")
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("Dao add....");
}
}
UserService
@Service
public class UserService {
//定义Dao类属性
//不需要使用set方法
@Autowired //根据类型进行注入
@Qualifier(value = "userDaoImpl1")//根据名称注入,因为一个接口可能有多个实现类
private UserDao userDao;
public void add(){
System.out.println("service add....");
userDao.add();
}
}
纯注解开发:
第一步:创建配置类,替代配置文件
@Configuration//将当前类作为配置类,代替xml配置文件
@ComponentScan(basePackages = ("com.zhujie"))
public class SpringConfig {
}
第二步:编写测试类
//使用纯注解开发
@Test
public void test2(){
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.add();
}