[Java]Spring-Day 1
[Java]Spring-Day1
学习使用工具
黑马2023新版Java视频教程 https://www.bilibili.com/video/BV1Fv4y1q7ZH?p=8&vd_source=03da0cdb826d78c565cd22a83928f4c2
Java程序员进阶之路 https://tobebetterjavaer.com/overview/java-can-do-what.html
黑马程序员SSM框架教程 https://www.bilibili.com/video/BV1Fi4y1S7ix?p=2&vd_source=03da0cdb826d78c565cd22a83928f4c2
JAVA三层架构 https://cloud.tencent.com/developer/article/1933722
JAVA静态工厂 https://developer.aliyun.com/article/862351
一、Spring Framework 4系列系统架构
- Core Container:核心容器,里面装了各种对象
- Beans
- Core
- Context
- SpEL
- AOP:面向切面编程 & Aspects:AOP思想实现
- Data Access/Integration:数据访问/数据集成
- JDBC
- ORM
- OXM
- JMS
- Transactions:事务
- Web:Web开发
- Test:单元测试与集成测试
JAVA的三层架构: 1、表示层(UI), 2、业务逻辑层(BLL), 3、数据访问层(DAL),又称持久层。
表示层:为用户提供交互操作界面。
业务逻辑层:负责关键业务的处理和数据的传递。复杂的逻辑判断和涉及到数据库的数据验证都需要在此做出处理。根据传入的值返回用户想得到的值,或者处理相关的逻辑。
数据访问层:负责数据库数据的访问。主要为业务逻辑层提供数据,根据传入的值来操作数据库,增、删、改、查。
二、Core Container
- IoC(控制反转)思想:对象的创建控制权由程序转移到外部。为了解决Java代码耦合度偏高的问题,提出解决方案:使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象。
- Spring提供了一个容器,称为IoC容器(即Core Container),用来充当IoC思想中的“外部”。IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
- DI(依赖注入):在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。
- 最终效果:解耦。使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系。
三、IoC入门案例
- 思路分析
- 管理什么?-对象
- 如何将被管理的对象告知IoC容器?-配置文件
- 被管理的对象交给IoC容器,如何获取到IoC容器?-接口
- IoC容器得到后,如何从容器中获取bean?-接口方法
- 案例实现
-
配置文件写法:配置文件命名为
applicationContext.xml
,内容为<bean id = "" class = ""/>
,id属性表示给bean命名,class属性标识给bean定义类型,即class的坐标。id属性在同一个上下文中不能重复 -
代码
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml") // 获取IoC容器 BookDao bookDao = (ClassType)ctx.getBean("") // 获取bean,引号内填bean的id
-
四、DI入门案例
-
思路分析
- 基于IoC管理bean
- 类A中使用new形式创建的对象B是否保留?-否
- 类A中需要的对象B如何进入到类A中?-提供方法
- 类A与对象B间的关系如何描述?-配置
-
案例实现
-
提供方法:通过set方法
-
配置文件关系写法:
<bean id = "bookDao" class = ""/> <bean id = "bookService" class = ""> <property name = "bookDao" ref = "bookDao"/> </bean>
property
标签表示配置当前bean
的属性,name
属性标识配置哪一个具体的属性,ref
属性标识参照哪一个bean
。
-
五、bean详解
-
配置
<bean id = "bookDao" name = "" class = "" scope = ""/>
name中可以增加别名,可以添加多个,以逗号、分号、空格分割。scope中可以定义bean作用范围,singleton为单例(默认),prototype为非单例
- 单例对象:是一种特殊的类,有且只有一个实例。
- 适合交给容器进行管理的bean:表现层对象、业务层对象、数据层对象、工具对象(可以复用的)
- 不适合交给容器进行管理的bean:封装实体的域对象
-
使用构造方法实例化
bean本质上就是对象,创建bean使用构造方法完成。一般来说,bean调用的是无参构造方法,如果没有提供无参构造方法,将抛出异常
BeanCreationException
。 -
使用静态工厂实例化
在 Java 中,获得一个类实例最简单的方法就是使用
new
关键字,通过构造函数来实现对象的创建。Fragment fragment = new MyFragment(); Date date = new Date();
不过在实际的开发中,我们经常还会见到另外一种获取类实例的方法:
Fragment fragment = MyFragment.newIntance(); Calendar calendar = Calendar.getInstance(); Integer number = Integer.valueOf("3");
像这样的不通过
new
,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法(Static factory method)
。public static Person getNewPerson(String name, int age, String skill) { if (StringUtils.isBlank(skill)){ return new Person(name, age); } return new Person(name, age, skill); }
以上是使用静态工厂方法来返回一个Person的实例对象,我们可以先不管方法体内的判断逻辑,只看返回值为一个Person对象。该静态工厂方法的功能和构造器类似,可以直接调用方法返回与构造器相同的结果。
优点:
- 实际在开发过程中,我们可能会根据业务定义多个构造函数。这时候可以直接通过静态工厂方法的名字区分,这样就更清晰明确。
- 可以通过写静态工厂方法来统一返回一个对象,也就是不必每次调用静态工厂方法的时候每次都创建一个新的对象。
- 通过该静态方法可以返回任何子类型的对象,且对调用者可以直接屏蔽实例化对象的类型。
- 静态工厂方法返回对象的类,可以是在定义静态工厂方法的时候不存在的。
在spring中,使用静态工厂实例化bean的方法如下:
<bean id = "bookDao" class = "" factory-method = ""/>
,class内填写静态工厂类,factory-method指定工厂内的方法。 -
使用实例工厂实例化
实例工厂与静态工厂基本相同,但静态工厂以static修饰,实例工厂不用static修饰。
在spring中,使用实例工厂实例化bean的方法如下:
<bean id = "bookFactory" class = ""/> <bean id = "bookDao" factory-method = "" factory-bean = "bookFactory"/>
先配置实例工厂bean,再配置需要的bean。
-
实例工厂的改良:FactoryBean
实例工厂的编写:
public class UserDaoFactoryBean implements FactoryBean<UserDao>{ //代替原始实例工厂中创建对象的方法 public UserDao getObject() throws Exception{ return new UserDaoImp1(); } public Class<?> getObjectType(){ return UserDao.class; } public boolean isSingleton(){ return true; //当false的时候就是非单例的 } }
bean的配置:
<bean id = "userDao" class="UserDaoFactoryBean">
-
bean的生命周期
- 初始化容器:
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(Set操作)
- 执行bean初始化方法
- 使用bean
- 关闭/销毁容器:执行bean销毁方法
public class BookDaoImp1 implements BookDao{ public void init(){ // 表示bean初始化对应的操作 } public void destroy(){ // 表示bean销毁时对应的操作 } }
配置:
<bean id = "bookFactory" class = "" init-method = "init" destory-method = "destroy"/>
或者在编写类时就加上接口:
public class BookDaoImp1 implements BookDao, InitializingBean, DisposableBean{ public void afterPropertiesSet() throws Exception{ // 表示bean初始化对应的操作 } public void destroy() throws Exception{ // 表示bean销毁时对应的操作 } }
配置时就不需要再指定
init-method
和destory-method
了。 - 初始化容器:
六、依赖注入
-
setter注入
-
简单类型
<bean id = "bookService" class = ""> <property name = "" value = ""/> </bean>
name指定需要注入的变量名,value指定值。指定值时需要带双引号,与类型本身的值无关,java自己会进行类型转换。
-
引用类型:参考DI入门案例中使用ref进行配置。
-
-
构造器注入:不使用set方法,而在构造方法中进行注入(即有参构造方法)
-
简单类型
<bean id = "bookService" class = ""> <constructor-arg name = "" value = ""/> </bean>
也可以用类型进行指定:
<bean id = "bookService" class = ""> <constructor-arg type = "int" value = ""/> <constructor-arg type = "java.lang.String" value = ""/> </bean>
也可以用顺序进行指定:
<bean id = "bookService" class = ""> <constructor-arg index = "0" value = ""/> <constructor-arg index = "1" value = ""/> </bean>
-
引用类型
<bean id = "bookService" class = ""> <constructor-arg name = "" ref = ""/> </bean>
依赖注入方式选择:强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现;可选依赖使用setter注入进行,灵活性强。Spring框架倡导使用构造器,自己开发的模块推荐使用setter注入。
-
七、依赖自动装配
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配,用于对引用类型依赖注入,不能对简单类型进行操作。
自动装配优先级低于setter注入与构造器注入。
自动装配方式:
-
按类型(常用):需要提供set方法。此时必须要保障容器中相同类型的Bean唯一。
<bean id = "bookService" class = "" autowire = "byType"/>
-
按名称:需要提供set方法。此时必须要保障容器中具有指定名称的bean。
<bean id = "bookService" class = "" autowire = "byName"/>
-
按构造方法(不常用)
八、集合注入
-
数组
<bean id = "bookService" class = ""> <property name = "array"> <array> <value>100</value> <value>200</value> </array> </property> </bean>
-
List
<bean id = "bookService" class = ""> <property name = "list"> <list> <value>one</value> <value>two</value> </list> </property> </bean>
-
Set
<bean id = "bookService" class = ""> <property name = "set"> <set> <value>one</value> <value>two</value> </set> </property> </bean>
-
Map
<bean id = "bookService" class = ""> <property name = "map"> <map> <entry key = "country" value = "china"> <entry key = "city" value = "anqing"> </map> </property> </bean>
-
Properties
<bean id = "bookService" class = ""> <property name = "propties"> <props> <prop key = "country">china</prop> <prop key = "city">anqing</prop> </props> </property> </bean>