今天开始spring框架的学习了,难度有明显的提升,坚持每天能够总结所学内容,加油加油~~
1.什么是Spring呢?
简单来说Spring框架是一个开放源代码的J2EE的应用程序框架,是针对bean的生命周期进行管理的轻量级容器.
1.1知识点包含哪些呢?
-
J2SE : 基础的Java语法
-
J2EE : Java企业级开发
-
J2ME : 移动端Java开发 手机QQ就是Java写的
-
bean : 由Spring容器管理的对象称之为bean!!!
-
轻量级 : 是指使用Spring容器的方式简单/便捷
-
容器 : Spring在内存中开辟了一大块空间来管理对象
1.2传统的项目开发是怎样的呢?
-
创建Dog类
package com.jt.demo1;
public class Dog {
public void hello(){
System.out.println("这是条狗子");
}
}
2.创建Cat类
package com.jt.demo1;
public class Cat {
public void hello(){
System.out.println("撸猫-噜噜噜~");
}
}
3.创建测试类
package com.jt.demo1;
public class User {
/**
* 分析这段代码有什么缺点:
* 1.如果用户需要切换属性.则手动的修改代码
* 2.每个宠物对象都与当前的类User紧紧的绑定在一起.后期维护不易!!
* 总结: 这样的程序设计耦合性高
*/
//用户需要调用hello方法
private static Cat cat = new Cat();
private static Dog dog = new Dog();
public static void main(String[] args) {
System.out.println("用户调用方法");
cat.hello();
dog.hello();
}
}
4.测试问题总结
1.如果一个类中的属性通过new的方式直接绑到了,就会产生类和属性耦合性高的问题
2.如果需要修改属性的类型,比如加个小猪类小鱼类就需要修改代码,后期的维护不方便
1.3面向接口开发(重点内容)
-
定义接口---暴露一套开发规则
package com.jt.demo2; public interface Pet { //接口的作用? 抽取一些公共的方法!!! void hello(); }
2.定义Pet接口的两个实现类
1.定义狗子类
package com.jt.demo2; public class Dog implements Pet{ @Override public void hello() { System.out.println("狗子来了嘿"); } }
2.定义猫儿类
package com.jt.demo2; public class Cat implements Pet{ @Override public void hello() { System.out.println("小猫 喵喵!!!"); } }
3.定义用户类
package com.jt.demo2; public class User { //1.用户可以使用接口当做属性 //2.面向接口开发! 以后方法的属性名称不用修改 private static Pet pet = new Cat();//多态!! public static void main(String[] args) { pet.hello(); } }
1.4 Spring核心-IOC介绍(重点)
1.现在存在的问题?
说明:目前虽然属性不用修改 了,但是Dog/Cat的对象还是和User类绑到在一起的,还是需要重复创建对象,还达不到解耦合的要求
2.IOC介绍
IOC全称是Inversion of Control,直译"控制反转",这是一种设计思想.对象创建的权利交由Spring框架来完成,由容器管理对象的生命周期
3.IOC入门案例
准备Dog类
准备spring.xml配置文件
注意:bean标签内配置的路径
编辑User测试对象
package com.jt.demo3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class User {
//IOC!!!
public static void main(String[] args){
//1.指定配置文件
String resource = "spring.xml";
//2.创建容器对象 加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext(resource);
//3.从容器中获取对象
Dog dog = context.getBean(Dog.class);
//4.调用对象的方法
dog.hello();
}
}
IOC对象创建---反射机制
package com.jt.demo3;
public class NewDog {
/*
1.该方法是通过反射的机制实例化对象!!!,反射是框架中的重点内容
2.反射机制:
Java中创建对象的常用方法之一,指定类型的路径,
之后通过关键方法.newInstance()实例化对象
类比: xxx.newInstance()~= new Dog();
3.精髓: 为什么使用反射而不是new呢?
因为第三方通过反射实力话对象可以实现解耦合
一般多用于框架中,因为框架不清楚用户需要什么,
只有程序跑起来才知道到底需要什么对象,扩展性好
4.异常说明:
1.运行时异常 运行时出错
2.编译异常/检查异常 编译时提示报错
*/
public static void main(String[] args) throws ClassNotFoundException,InstantiationException, IllegalAccessException {
Dog dog = (Dog) Class.forName("com.jt.demo3.Dog").newInstance();
dog.hello();
}
}
4.IOC实现的原理
容器的数据结构: K-V形式的键值对类型. Map<K,V> 其中的key=bean中的ID value=实例化对象
程序的执行过程:
1.指定配置文件的名称
2.当Spring容器加载配置文件的时候,当按照顺序执行bean标签时开始创对象
3.Spring通过bean标签中的class属性获取类型的路径,之后通过反射机制,实例化对象(必须有无参构造) 特别提醒下:这个地方不能有含参构造,但是不代表反射不能有含参构造
4.bean中的ID当做Map中的key,将实例化的对象存到Map中,当做value,至此Spring容器启动成功
5.当用户需要获取对象是, 可以通过key或者类型 获取对象
1.5 Spring注解开发
说明:10年前那么开发是必须会对xml文件进行繁琐的配置的,但是引入springboot之后,基本之后就不需要使用xml文件配置了,一般都使用注解开发,但是配置文件还是得有所了解
编辑配置类
效果:和配置文件类似
注解的作用:标识/标记
注解1 : @Configuration 标记这个类为配置注解
注解2 : @Bean 告诉Spring容器,当前方法的名称为Map中的key;返回值是Map中的value.
注解3 : @ComponentScan("com.jt.demo4") 这个是包扫描注解,让spring注解生效
注解4 : @Scope("prototype") 多例模型
@Scope("singleton") 如果不写默认的就是单例,注意括号内的内容,面试常挖坑
注解5 : @Lazy 懒加载开启,只对单例模式生效,多例模式都是懒加载,lazy注解不能控制
package com.jt.demo4;
import org.springframework.context.annotation.*;
@Configuration//配置注解
@ComponentScan("com.jt.demo4")//包扫描
public class SpringConfig {
@Bean//dog()方法是key,new Dog()是value
//@Scope("singleton")默认的就是单例
@Lazy//懒加载开启,只对单例模式生效,多例模式都是懒加载,lazy注解不能控制
@Scope("prototype")//这个注解表示多例对象,不写就默认单例
public Dog dog(){
return new Dog();
}
}
测试下
package com.jt.demo4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class User {
//该测试类,测试单例和多例对象
public static void main(String[] args) {
//创建容器对象
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
//从容器中获取对象
Dog dog = context.getBean(Dog.class);
context.getBean(Dog.class);
context.getBean(Dog.class);
context.getBean(Dog.class);
context.getBean(Dog.class);
//通过对象调用方法
dog.hello();
}
}
单例和多例的问题说明
单例对象 : Spring中保存一份对象
多例对象 : Spring容器负责创建多次对象,内存中有对象多份
Spring容器默认条件下,对象都是单例对象. 节省内存空间!!!
Spring容器提供了多例对象的方法,一般适用 数据库链接/资源链接等功能
Spring中的懒加载是怎样的?
回顾下之前学过的懒汉:
懒汉式 : 字面意思就能理解,就是当用户需要的时候再创建对象
饿汉式 : 无论是否需要都创建对象
懒加载 : 默认条件下,Spring容器启动的时候都会进行实例化对象,如果用户使用时创对象,则使用懒加载的机制
规则 :
1.spring容器启动的时候,对象自己创建 ,这不是懒加载
2.当用户使用时创对象,是懒加载
特别注意:懒加载只能控制单例模式,对多例模式无效,因为多例模式都是懒加载的规则