目录
三.bean作用范围配置(你创建的Bean是一个对象还是多个对象)
1.由此可见Spring默认造的类型是单例的,但是我们想造一个非单例的该怎么办?
四.我们这个单例bean是怎么造出来的呢?(bean的实例化的过程)
1.bean的三种实例化方法--静态工厂(近些年比较少,早些年比较多)了解即可
3.bean的三种实例化方法--实例工厂与FactoryBean
一.bean的基础配置
二.bean的别名配置
(根据每个人的习惯不同,为了让每个人都可以适应,所以bean可以起多个名字,)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao1" name="dao,dao2,dao3,dao4,dao5" class="com.itheima.dao.impl.BookDaoImpl" ></bean>
<bean id="BookService" name="Service,Service1,Service2,Service3" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao1"></property>
</bean>
</beans>
1.在配置文件之中,name是和id同等效用的
2.如果你写了一个没有的id,或者name则会出异常,异常为NoSuchBeanDefinitionException
三.bean作用范围配置(你创建的Bean是一个对象还是多个对象)
1.由此可见Spring默认造的类型是单例的,但是我们想造一个非单例的该怎么办?
通过配置的方式完成
2.为什么bean默认为单例?
1.适合交给容器进行管理bean(以下为适合造单例)(能反复用)
表现层对象(servlet)
业务层对象(service)
数据层对象(dao)
工具对象(比如util)
2.不适合交给容器管理的bean(不可以反复使用)
封装实体的域对象
(bean的作用范围,它实际上是控制我们bean创建的实例的数量的)
四.我们这个单例bean是怎么造出来的呢?(bean的实例化的过程)
1.bean的三种实例化方法--构造方法(现在常用)
1.提供可访问的构造方法(无参)(idea快捷键 alt + insert)
无论是private还是public都可以被外部的调用,(反射)
Spring创建bean的时候,调用的的是无参的构造方法,有参报错BeanCreationException
package com.itheima.dao.impl;
import com.itheima.dao.BookDao;
public class BookDaoImpl implements BookDao {
//无论是private还是public都可以被外部的调用,(反射),Spring创建bean的时候,调用的的是无参的构造方法,有参报错BeanCreationException
private BookDaoImpl() {
System.out.println("BookDaoImpl中的构造方法已经被调用");
}
@Override
public void save() {
System.out.println("来自BookDao的实现类BookDaoImpl");
}
}
2.编写Spring配置文件,没有写Di
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl">
</bean>
3.运行
package com.itheima.factory;
import com.itheima.dao.BookDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppForInstanceBook {
public static void main(String[] args) {
//对Spring的配置文件进行实例化
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//取bean
BookDao bookDao = (BookDao) ctx.getBean("BookDao");
//取方法
bookDao.save();
}
}
4.效果
5.错误示范(有参构造方法,报错信息)
1.bean的三种实例化方法--静态工厂(近些年比较少,早些年比较多)了解即可
(早些年做程序的常用方式,找对象不要自己new,利用工厂的方式进行new,实际上就是在工厂内部已经new过了,做一定结构的解耦)(如果这种方式来进行new,Spring该如何利用IOC进行管理呢?)
1.编写静态工厂
package com.itheima.factory;
import com.itheima.dao.OrderDao;
import com.itheima.dao.impl.OrderDaoImpl;
public class OrderDaoFactory {
public static OrderDao getOderDao(){
System.out.println("工厂类的其他配置启用");
return new OrderDaoImpl();
}
}
2.编写Spring的配置文件(和普通的不一样)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 方式一 构造方法进行管理-->
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl">
</bean>
<!-- 方式二 静态工厂进行管理 利用factory-method告诉Spring工厂里面那个方法是进行造对象的-->
<bean id="OrderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOderDao">
</bean>
</beans>
3.复写OrderDao的实现类OrderDaoImpl的方法
package com.itheima.dao.impl;
import com.itheima.dao.OrderDao;
public class OrderDaoImpl implements OrderDao {
@Override
public void save() {
System.out.println("OrderDao实现类中的OrderDaoImpl中的save被调用");
}
}
4.运行
package com.itheima;
import com.itheima.dao.OrderDao;
import com.itheima.factory.OrderDaoFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppForInstanceOrder {
public static void main(String[] args) {
/* //*老方法
//获取OrderDaoFactory工厂类的的实现方法---这一步相当于已经实现了new OrderDaoImpl
OrderDao oderDao = OrderDaoFactory.getOderDao();
//获取OrderDaoImpl的方法
oderDao.save();*/
//Spring新方法,获取Spring中的配置文件
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean
OrderDao orderDao = (OrderDao) ctx.getBean("OrderDao");
//调取方法
orderDao.save();
}
}
5.效果
3.bean的三种实例化方法--实例工厂(非静态)
1.UserDaoImpl UserDao的实现类
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("实现了UserDao的实现类UserDaoImpl");
}
}
2.UserDaoFactory UserDao(非静态)工厂
package com.itheima.factory;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
public class UserDaoFactory {
public UserDao getUserDao(){
System.out.println("工厂类的其他配置启用");
return new UserDaoImpl();
}
}
3.AppForInstanceUser运行
package com.itheima;
import com.itheima.dao.UserDao;
import com.itheima.factory.UserDaoFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppForInstanceUser {
public static void main(String[] args) {
/*老方法
//1.创建工厂对象
UserDaoFactory udf = new UserDaoFactory();
//2.获取相对应的方法,在这一步实现工厂其他配置
UserDao userDao = udf.getUserDao();
//3.实现UserDaoImpl中的方法
userDao.save();
*/
//新方法 1.对配置文件进行实例化
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//取bean
UserDao userDao = (UserDao) ctx.getBean("userDao");
//取方法
userDao.save();
}
}
4.Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- <!– 方式一 构造方法进行管理–>
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl">
</bean>
<!– 方式二 静态工厂进行管理 利用factory-method告诉Spring工厂里面那个方法是进行造对象的–>
<bean id="OrderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOderDao">
</bean>-->
<!-- 方式三 实例工厂(非静态)
1.造工厂的bean
2.用里面的那个方法造对象()
factory-bean指的是这个工厂的实例在哪
factory-method指的是那个方法是进行造对象的
-->
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"></bean>
<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"></bean>
</beans>
5.效果
4.bean的三种实例化方法--FactoryBean与实例工厂稍许不同(非静态)(重点,之后会常用)
注意:
相较于方式三,上一个方式,这个工厂继承了FactoryBean,三种方法好用,具体的东西还是卸载代码里面了,由于和方式三的区别只有Factory与Spring配置文件的区别,所以以下只写三种
1.UserDaoFactoryBean 与继承了FactroyBean
值得注意的是FactroyBean接口中getObject造出的对象才是Spring中引用的对象
package com.itheima.factory;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import org.springframework.beans.factory.FactoryBean;
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法--也就是告诉你(以后创建对象方法名不用制定了,统一都叫这个名字)
@Override
public UserDao getObject() throws Exception {
System.out.println("通过了UserDaoFactoryBean");
return new UserDaoImpl();
}
//说你这个对象是什么类型的,然后把字节码放到上面
@Override
public Class<?> getObjectType() {
return UserDao.class;
}
//这个代表了你实现的方法是单例还是非单例的,return true代表单例,return false代表的非单例的对象,不写默认为true
@Override
public boolean isSingleton() {
return true;
}
}
2.Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- <!– 方式一 构造方法进行管理–>
<bean id="BookDao" class="com.itheima.dao.impl.BookDaoImpl">
</bean>
<!– 方式二 静态工厂进行管理 利用factory-method告诉Spring工厂里面那个方法是进行造对象的–>
<bean id="OrderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOderDao">
</bean>-->
<!-- 方式三 实例工厂(非静态)
1.造工厂的bean
2.用里面的那个方法造对象()
factory-bean指的是这个工厂的实例在哪
factory-method指的是那个方法是进行造对象的
-->
<!-- <bean id="userFactory" class="com.itheima.factory.UserDaoFactory"></bean>
<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"></bean>-->
<!-- 方式四:方式三的变种 使用FactoryBean实例化bean-->
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean" ></bean>
</beans>
3.效果