XML注入Bean 笔记
一、set方式注入
value:引用这个对象名字的字符串;直接设置一个值(赋一些简单类型的值)
ref:引用的这个对象(可引用其他的bean对象)
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String name;
private String age;
public void setAge(String age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
<!--set 属性注入-->
<bean id="UserDao" class="org.example.dao.impl.UserDaoImpl"/>
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
<property name="name" value="Jack"></property>
<property name="age" value="18"></property>
<property name="userDao" ref="UserDao"/>
</bean>
带有特殊字符的value 和给定默认空值
<bean d="userService" class="org.example.service.impl.UserServiceImpl">
<!-- 特殊符号 例如<Jack>报错 可以把带特殊符号内容写到CDATA-->
<property name="name">
<value><![CDATA[<Jack>]]></value>
</property>
<!--设置属性null 空值-->
<property name="name"/>
<null></null>
</property>
</bean>
二、有参构造函数注入
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String name;
private String age;
//有参构造注入
public UserServiceImpl(UserDao userDao, String name, String age)
{
this.userDao = userDao;
this.name = name;
this.age = age;
}
}
<bean id="UserDao" class="org.example.dao.impl.UserDaoImpl"/>
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="name" value="Jack"></constructor-arg>
<constructor-arg name="userDao" ref="UserDao"></constructor-arg>
</bean>
三、工厂方法及静态工厂方法注入
public class BookFactory {
//非静态方法
public Book createBookObj(){
Book book = new Book();
book.setName("《三国演义》");
return car;
}
//静态方法
public static Book createStaticBookObj(){
Book book = new Book();
book.setName("《三国演义》");
return car;
}
}
工厂非静态方式注入
<bean id="BookFactory" class="org.example.BookFactory"/>
<bean id="book" factory-bean="BookFactory" factory-method="createBookObj"/>
工厂静态方式注入,无需创建工厂类实例
<bean id="book" factory-bean="org.example.BookFactory" factory-method="createStaticBookObj"/>
四、autowire自动装配(byName 和 byType)
public class UserServiceImpl implements UserService {
private String userName;
private UserDao userDao;
private UserDao userDao1;
private UserDao userDao2;
public void setuserName(String userName) {
this.userName = userName;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setUserDao1(UserDao userDao1) {
this.userDao1 = userDao1;
}
public void setUserDao2(UserDao userDao2) {
this.userDao2 = userDao2;
}
}
byName注入
<bean id="UserDao" class="org.example.dao.impl.UserDaoImpl"/>
<bean id="UserDao1" class="org.example.dao.impl.UserDao1Impl"/>
<bean id="UserDao2" class="org.example.dao.impl.UserDao2Impl"/>
// byName 以上Bean的Id 需要和 UserService 的属性名对应且Bean的id要唯一
<bean id="UserService" class="org.example.service.impl.UserServiceImpl" autowire="byName">
<property name="userName" value="Jack"/>
</bean>
byType注入
<bean id="A" class="org.example.dao.impl.UserDaoImpl"/>
<bean id="B" class="org.example.dao.impl.UserDao1Impl"/>
<bean id="C" class="org.example.dao.impl.UserDao2Impl"/>
// byName 以上Bean的class类型 需要和 UserService 的属性类型对应
<bean id="UserService" class="org.example.service.impl.UserServiceImpl" autowire="byType">
<property name="userName" value="Jack"/>
</bean>
总结
byName: Bean的Id值要全局唯一,且要与当前Bean的属性名称要一一对应
byType: Bean的class的类型需要与当前Bean的成员属性对应,Id名称可以随意
五、Array List Map Set 属性注入
public class UserServiceImpl implements UserService {
//数组类型
private String[] arrays;
//List 集合类型
private List<String> lists;
//Map 集合类型
private Map<String,String> maps;
//set 集合类型
private Set<String> sets;
//List 集合对象类型
private List<Course> courseList;
//List 集合类型 util方式注入
private List<String> hobbyList;
public void setArrays(String[] arrays) {
this.arrays = arrays;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public void setMaps(Map<String,String> maps) {
this.maps = maps;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
public void setHobbyList(List<String> hobbyList) {
this.hobbyList = hobbyList;
}
}
<bean id="userService" class="org.example.service.impl.UserServiceImpl">
//数组类型注入
<property name="arrays">
<array>
<value>游泳</value>
<value>唱歌</value>
<value>王者荣耀</value>
</array>
</property>
//List集合类型注入 方式一
<property name="lists">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
//List集合类型注入 方式二使用util方式
<property name="hobbyList" ref="hobbyListDemo"></property>
//Map集合类型注入
<property name="maps">
<map>
<entry key="1" value="java"></entry>
<entry key="2" value="php"></entry>
<entry key="2" value="go"></entry>
</map>
</property>
//Set集合类型注入
<property name="sets">
<set>
<value>Mysql</value>
<value>Vue</value>
</set>
</property>
//List集合对象注入
<property name="courseList">
<list>
<ref bean="Course1"></ref>
<ref bean="Course2"></ref>
</list>
</property>
</bean>
//使用util 需要引入util命名空间
//xmlns:util="http://www.springframework.org/schema/util
//xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
<util:list id="hobbyListDemo">
<value>爬山</value>
<value>跑步</value>
<value>听音乐</value>
</util:list>
//创建多个course对象
<bean id="Course1" class="org.example.Course">
<property name="cname" value="Mybatis框架"></property>
</bean>
<bean id="Course2" class="org.example.Course">
<property name="cname" value="Spring框架"></property>
</bean>
六、使用外部配置文件
//pom.xml 引入数据库坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
新建 resources -> jdbc.properties配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my_gin?useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
在bean.xml中使用
//使用context名称空间
//xmlns:context="http://www.springframework.org/schema/context"
//http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
//context 引入外部属性文件
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
七、Bean的生命周期
定义BookClass
public class Book {
private String bookName;
public void setBookName(String bookName) {
System.out.println("【setBookName】注入属性bookName");
this.bookName = bookName;
}
public void test() {
System.out.println("================================");
System.out.println(bookName);
}
public void initFunction() {
System.out.println("================================");
System.out.println("【initFunction】Bean实例化了");
}
public void destroyFunction() {
System.out.println("【destroyFunction】容器销毁当前Bean调用");
}
}
两个生命周期函数:init-method="initFunction"
destroy-method="destroyFunction"
<bean id="book" class="org.example.demo.Book" init-method="initFunction" destroy-method="destroyFunction"></bean>
调用测试
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml");
Book book = ctx.getBean("book",Book.class);
book.test();
ctx.close();
查看结果
【setBookName】注入属性bookName
================================
【initFunction】Bean实例化了
================================
《三国演义》
================================
【destroyFunction】容器销毁当前Bean调用
Process finished with exit code 0
八、Bean的后置处理器 BeanPostProcessor
自定义后置处理器 实现BeanPostProcessor接口,并实现postProcessBeforeInitialization,postProcessAfterInitialization 两个方法
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("================================");
System.out.println("在属性注入前执行");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("================================");
System.out.println("在属性注入后执行");
return bean;
}
}
Bean.xml配置
<bean id="MyBeanPost" class="org.example.utils.MyBeanPost"></bean>
定义BookClass
public class Book {
private String bookName;
public void setBookName(String bookName) {
System.out.println("【setBookName】注入属性bookName");
this.bookName = bookName;
}
public void test() {
System.out.println("================================");
System.out.println(bookName);
}
public void initFunction() {
System.out.println("================================");
System.out.println("【initFunction】Bean实例化了");
}
public void destroyFunction() {
System.out.println("【destroyFunction】容器销毁当前Bean调用");
}
}
两个生命周期函数:init-method="initFunction"
destroy-method="destroyFunction"
<bean id="book" class="org.example.demo.Book" init-method="initFunction" destroy-method="destroyFunction"></bean>
调用测试
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml");
Book book = ctx.getBean("book",Book.class);
book.test();
ctx.close();
查看结果
【setBookName】注入属性bookName
================================
【后置处理器postProcessBeforeInitialization】在属性注入前执行
================================
【initFunction】Bean实例化了
================================
【后置处理器postProcessAfterInitialization】在属性注入后执行
================================
《三国演义》
================================
【destroyFunction】容器销毁当前Bean调用
Process finished with exit code 0