Spring:IOC的原理和使用 |
您所在的位置:网站首页 › spring的ioc的三种实现方式 › Spring:IOC的原理和使用 |
一. IOC容器底层原理
本质上就是 对象工厂 + 反射 eg: 将xml解析得到dao类包路径,工厂模式factory通过反射用类名创建出对象返回,service类直接通过 factory调用userdao,进一步降低耦合 实际上,factory经过Spring的进一步优化就是IOC容器
指Spring操作对象和Spring注入属性 2.操作方式 2.1 基于xml配置文件的方式官网:尽管 XML 一直是定义配置元数据的传统格式,但你可以通过提供少量的 XML 配置来指示容器使用 Java 注释或代码作为元数据格式,从而声明性地支持这些附加的元数据格式。 2.1.1 创建对象 复制代码 2.1.2 基于set方法注入属性(DI:依赖注入) 创建类,定义属性和对应的set方法 public class Book { //创建属性 private String bname; //创建属性对应的set方法 public void setBname(String bname) { this.bname = bname; } } 复制代码 2.1.3 基于有参构造函数注入属性 (1)传统方式:创建类,构建有参函数 public class Orders { //属性 private String oname; private String address; //有参数构造 public Orders(String oname,String address) { this.oname = oname; this.address = address; } } 复制代码 2.1.4 基于p命名空间注入属性 > 复制代码 2.1.5 基于外部bean注入属性 public class UserService {//service类 //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { System.out.println("service add..............."); userDao.update();//调用dao方法 } } public class UserDaoImpl implements UserDao {//dao类 @Override public void update() { System.out.println("dao update..........."); } } Spring XML 复制代码 2.1.6 基于内部bean注入属性 //部门类 public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } } //员工类 public class Emp { private String ename; private String gender; //员工属于某一个部门,使用对象形式表示 private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } } spring xml 复制代码 2.1.7 基于内部bean注入属性 - 级联赋值 复制代码 //方式二:生成dept的get方法(get方法必须有!!) public Dept getDept() { return dept; } 复制代码 2.1.8 注入集合属性1、注入数组类型属性 2、注入 List 集合类型属性 3、注入 Map 集合类型属性 //(1)创建类,定义数组、list、map、set 类型属性,生成对应 set 方法 public class Stu { //1 数组类型属性 private String[] courses; //2 list集合类型属性 private List list; //3 map集合类型属性 private Map maps; //4 set集合类型属性 private Set sets; public void setSets(Set sets) { this.sets = sets; } public void setCourses(String[] courses) { this.courses = courses; } public void setList(List list) { this.list = list; } public void setMaps(Map maps) { this.maps = maps; } 复制代码 java课程 数据库课程 张三 小三 MySQL Redis 复制代码 2.1.9 注入属性时在集合里面设置对象类型的值 //学生所学多门课程 private List courseList;//创建集合 public void setCourseList(List courseList) { this.courseList = courseList; } 复制代码 复制代码 2.1.10 注入属性时 提取公共集合 > 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"> 易筋经 九阴真经 九阳神功 复制代码 2.1.11 注入属性时 自动装配bytype要注意多个同type bean会报错 2.1.12 引入外部属性文件创建外部属性文件,properties 格式文件,写数据库信息jdbc.properties prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/userDb prop.userName=root prop.password=root 复制代码 复制代码 2.2 基于注解的方式 日常开发通常基于springboot实现 2.2.1 创建对象 1.第一步 引入依赖 (引入spring-aop jar包) 2.第二步 开启组件扫描 在xml文件引入context命名空间 复制代码 3.第三步 创建类,在类上面添加创建对象注解 //在注解里面 value 属性值可以省略不写, //默认值是类名称,首字母小写 //UserService -- userService @Component(value = "userService") //注解等同于XML配置文件: public class UserService { public void add() { System.out.println("service add......."); } } 复制代码 4、可选 开启组件扫描细节配置 复制代码 2.2.2 基于@Autowired注入属性 1.@Autowired:根据属性类型进行自动装配 (1) 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解 (2)在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解 @Service public class UserService { //定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired private UserDao userDao; public void add() { System.out.println("service add......."); userDao.add(); } } //Dao实现类 @Repository //@Repository(value = "userDaoImpl1") public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("dao add....."); } } 复制代码 2.2.3 基于@Qualifier注入属性 @Qualifier:根据名称进行注入,这个@Qualifier 注解的使用,和上面@Autowired 一起使用 //定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired //根据类型进行注入 //根据名称进行注入(目的在于区别同一接口下有多个实现类,只通过@autowire根据类型就无法选择,从而出错!) @Qualifier(value = "userDaoImpl1") private UserDao userDao; 复制代码 2.2.4 基于@Resource注入属性 @Resource:可以根据类型注入,也可以根据名称注入(它属于javax包下的注解,spring官方不推荐使用!) //@Resource //根据类型进行注入 @Resource(name = "userDaoImpl1") //根据名称进行注入 private UserDao userDao; 复制代码 2.2.5 基于@Value注入属性 @Value(value = "abc") private String name 复制代码 3.完全注解开发 3.1 创建配置类,替代 xml 配置文件 @Configuration //作为配置类,替代 xml 配置文件 @ComponentScan(basePackages = {"com.atguigu"}) //替代xml的扫描路径 public class SpringConfig { } 复制代码 3.2 编写测试类 @Test public void testService2() { //加载配置类 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); } 复制代码 四.bean作用域 在 Spring 里面,默认情况下,bean 是单实例对象,下面进行作用域设置: (1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例 (2)scope 属性值 第一个值 默认值,singleton,表示是单实例对象 第二个值 prototype,表示是多实例对象 (3)singleton 和 prototype 区别 a)singleton 单实例,prototype 多实例 b)设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象 ;设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象 复制代码 五.bean生命周期 5.1 什么是生命周期从对象创建到对象销毁的过程 5.2 bean 生命周期 (1)通过构造器创建 bean 实例(无参数构造) (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) (3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization (4)调用 bean 的初始化的方法(需要进行配置初始化的方法) (5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization (6)bean 可以使用了(对象获取到了) (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法) 复制代码 5.3 演示 bean 生命周期 : public class Orders { //无参数构造 public Orders() { System.out.println("第一步 执行无参数构造创建 bean 实例"); } private String oname; public void setOname(String oname) { this.oname = oname; System.out.println("第二步 调用 set 方法设置属性值"); } //创建执行的初始化的方法 public void initMethod() { System.out.println("第三步 执行初始化的方法"); } //创建执行的销毁的方法 public void destroyMethod() { System.out.println("第五步 执行销毁的方法"); } } 复制代码 public class MyBeanPost implements BeanPostProcessor {//创建后置处理器实现类 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前执行的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后执行的方法"); return bean; } } 复制代码 复制代码 @Test public void testBean3() { // ApplicationContext context = // new ClassPathXmlApplicationContext("bean4.xml"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("orders", Orders.class); System.out.println("第四步 获取创建 bean 实例对象"); System.out.println(orders); //手动让 bean 实例销毁 context.close(); } 复制代码 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |