IOC操作Bean管理
1、Bean管理
- Bean管理指的是两个操作
- Spring创建对象
- Spring注入属性
2、Bean管理操作有两种方式
-
基于xml配置文件方式实现
-
基于xml方式创建对象
<!--创建User类的对象--> <bean id="user" class="com.dxz.demo.User"></bean>
(1)在spring配置文件中使用bean标签,标签里添加对应的属性,就可以实现对象创建
(2)在bean标签有很多属性,介绍常用属性
*id:唯一标识
*class:包名和类名
*name:作用和id属性,其中可以加特殊符号
(3)创建对象时候,默认也是执行无参的构造函数
-
基于xml方法注入属性
-
DI:依赖注入,就是注入属性(是IOC的一种具体实现)需要在创建对象的基本上。
(1)使用set方法进行注入
[1]java中最基本的set方法
[2]在bean标签下创建 property标签,包name 和value属性,name为属性 名称,value为属性的值
(2)使用有参数的构造进行注入
利用constructor-arg标签进行注入,包括name、value两个属性,也可以用index属性表示第几个参数,但大多数利用,name属性。
-
p名称空间注入
-
使用p名称空间注入,可以简化基于xml配置方式xmlns:p=“http://www.springframework.org/schema/p”
-
进行属性注入,在bean标签里面进行操作
<bean id="book1" class="com.dxz.demo.Book" p:author="小段" p:name="实践简史"></bean>
-
-
-
-
IOC操作Bean管理(xml注入其他类型属性)
-
字面量
(1)null值
<property name="address"> <null/> </property>
-
属性值包含特殊符号
(1)把<>进行转义:<,>
(2)把带特殊符号内容写到CDATA
<property name="address"> <value> <![CDATA[<<南京>>]]> </value> </property>
-
注入属性-外部bean
-
创建两个类service类和dao类
-
在service调用dao里面的方法
-
在spring配置文件中进行配置
-
首先创建两个类的对象,在service对象中利用property标签中的ref属性值将dao类的对象进行赋值。
<bean id="service" class="包名+类名"> <property name="dao" ref="userDao"></property> </bean> <bean id="userDao" class="包名+类名"></bean>
-
-
注入属性-内部bean和级联赋值
-
一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多
-
在实体之间一对多的关系
-
在spring中进行配置
-
bean标签可以在property标签中嵌套,进行给对象属性进行赋值。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TbZABI02-1638845336664)(C:\Users\Master\AppData\Roaming\Typora\typora-user-images\image-20211203092114779.png)]
-
-
注入属性-级联赋值
-
第一种方式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cey5SsxB-1638845336669)(C:\Users\Master\AppData\Roaming\Typora\typora-user-images\image-20211203092500784.png)]
-
第二种方式:
在这里一定要注明get方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jda47DLh-1638845336670)(C:\Users\Master\AppData\Roaming\Typora\typora-user-images\image-20211203092948860.png)]
-
-
-
IOC操作Bean管理(xml注入集合属性)
-
注入数组类型属性
-
注入list集合类型属性
-
注入Map集合类型属性
-
注入Set集合类型到属性
<bean id="" class=""> <property name=""> <!--这里举三个例子关于array,list,set--> <array> <value>内容1</value> </array> <list> <value>内容2</value> </list> <set> <value>内容3</value> </set> <!--举一个关于map的例子--> <map> <entry key="" value=""></entry> </map> </property>
-
假如集合中都是对象的话
<bean id="" class=""> <property name=""> <list> <ref bean="name1"></ref> <ref bean="name2"></ref> </list> </property> </bean> <bean id="name1" class=""> <property name="" value=""></property> </bean> <bean id="name2" class=""> <property name="" value=""></property> </bean>
-
基于注解方式实现,利用util记性属性的注入。
-
首先添加对util的引用
在beans标签中添加属性
xmlns:util="http://www.springframework.org/schema/util" xsi:三处beans改为util即可
-
利用util进行属性注入
<util:list id="booklist"> <value>book1</value> <value>book2</value> <value>book3</value> </util:list> <bean id="" class="包名+类名"> <property name="list" ref="booklist"></property> </bean>
-
-
-
IOC操作Bean管理(FactoryBean)
-
IOC操作Bean管理(bean作用域)
-
在spring里面,设置创建bean实例是单实例还是多实例
-
在spring里面默认情况下,bean是单实例对象
-
设置单实例还是多实例
(1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
(2)scope属性值
第一个值:singleton表示是单实例对象
第二个值:prototype,表示是多实例对象
第三个是:request,表示在web中进行请求。
第四个是:session,同样表示在session中进行创建对象
(3)singleton和prototype区别
第一个区别:singleton为单实例prototype为多实例。
第二个区别:设置scope值是singleton时候加载spring配置文件时候就会创建单实例对象,而prototype,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
-
-
IOC操作Bean管理(bean生命周期)
-
生命周期:从对象创建到对象销毁的过程
-
bean生命周期
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其他bean引用(调用set方法)
- 调用bean的初始化方法(需要进行配置)
- bean可以使用了(对象获取到了)
- 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
-
演示bean生命周期
(1)首先写java类
public class MyPhone { public MyPhone(){ System.out.println("第一步通过bean构造器进行构造实例"); } private String phoneName; public void setPhoneName(String phoneName){ System.out.println("第二步为bean设置属性值,和对其他的bean对象进行初始化"); this.phoneName = phoneName; } public void initMethod(){ System.out.println("第三步调用bean初始化方法"); } public void destroyMethod(){ System.out.println("第五步调用bean销毁方法"); } }
(2)然后写xml配置文件
<bean id="phone" class="com.dxz.demo.phone.MyPhone" init-method="initMethod" destroy-method="destroyMethod"> <property name="phoneName" value="三星"></property> </bean>
(3)最后写测试方法
@Test public void testPhone(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); MyPhone phone = context.getBean("phone",MyPhone.class); System.out.println("第四步获取到bean对象"); context.close(); }
-
bean的后置处理器,bean生命周期有七步
分别在第二步和第三部的后面添加
把bean实例传递bean后置处理器的方法
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其他bean引用(调用set方法)
- 把bean实例传递bean后置处理器的方法
- 调用bean的初始化方法(需要进行配置)
- 把bean实例传递bean后置处理器的方法
- bean可以使用了(对象获取到了)
- 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
-
首先重写将bean对象传递给bean后置处理器的方法
public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化之前执行的把bean实例传递给bean后置处理器的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化之后执行的把bean实例传递给bean后置处理器的方法"); return bean; } }
其次再写bean.xml的配置文件
<bean id="myBeanPost" class="com.dxz.demo.phone.MyBeanPost"></bean>
-
-
IOC操作Bean管理(xml自动装配)
-
IOC操作Bean管理(外部属性文件)
-
直接配置数据库信息
(1)配置德鲁伊连接池
(2)引入德鲁伊连接数据库jar包
-
通过引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties格式文件,写入数据库信息
创建jdbc.properties文件写入一下内容
prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/userDb prop.userName=root prop.password=DXZDXZ4811
(2)把外部properties属性文件引入到spring配置文件中
*引入context名称空间改变beans标签中的属性,添加context
并且在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管理(基于注解方式)
-
什么是注解
(1)注解就是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值,…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化xml配置
-
Spring针对Bean管理中创建对象提供注解
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
*上面的四个注解功能是一样的,都可以创建bean实例
-
基于注解方式实现对象创建
第一步引入aop.jar依赖
第二步开启组件扫描
利用context标签进行扫描
<context:component-scan base-package="包名"></context:component-scan>
如果要扫描多个包,
可以使用逗号隔开或者扫描包上层目录
第三步创建Component注解的类
@Component (value = "myCup") public class MyCup { public void add(){ System.out.println("add...."); } }
第四步测试
@Test public void testCup(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); MyCup myCup = context.getBean("myCup",MyCup.class); System.out.println("获取到MyCup对象"); myCup.add(); }
-
利用context标签进行扫描的小细节
<!--扫描注解 use-default-filters="false表示不使用默认的扫描 include-filter表示扫描Component注解的类 --> <context:component-scan base-package="com.dxz.demo" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> </context:component-scan> <!--扫描注解 exclude-filter表示不扫描Component注解的类 --> <context:component-scan base-package="com.dxz.demo"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/> </context:component-scan>
-
基于注解方式实现属性注入
-
@Autowired
根据属性类型进行自动装配
第一步把service和dao对象创建,在service和dao类添加创建对象注解
第二步在service注入dao对象,在service类添加dao类型属性,在属性上面使用注解
@Service public class CupService { @Autowired private MyCup myCup1; public void add(){ System.out.println("Service....."); myCup1.add(); } }
-
@Qualifier
根据属性名称进行注入
和上面的@Autowired一起使用
@Service public class CupService { @Autowired @Qualifier(value = "myCup") private MyCup myCup1; public void add(){ System.out.println("Service....."); myCup1.add(); } }
-
@Resource
可以根据类型可以根据名称注入
但是这个注解是属于javax包
-
@Value
注入普通类型属性
@Value(value="abc") private String name;
-
-
完全注解开发
-
创建配置类替代xml配置文件
@configuration//作为配置类,替代xml配置文件 @componentScan(basePackages={"com.dxz"} public class SpringConfig{ }
-
编写测试类
public void testService2(){ ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService",UserService.class); System.out.println(userService); userService.add(); }
-
-