1.什麼是架構
架構(Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件執行個體間互動的方法;另一種定義認為,架構是可被應用開發者定制的應用骨架。前者是從應用方面而後者是從目的方面給出的定義。
2. Java中的架構
Struts HiberNate Spring SpringMvc SpringBoot
3. Struts2
Struts2是一個基于MVC設計模式的Web應用架構,它本質上相當于一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的資料互動
4. HiberNate
- 開源的對象關系映射架構
- 對jdbc的封裝的架構
- 與pojo(JavaBean)建立映射關系
5. Spring
應用于web層的架構
JavaBean的管理
6. Java企業級開發的演化
- Servlet + Java Bean
- Servlet + Java Bean + Jsp
- Struts2 + Spring + HiberNate(SSH)
- Spring Mvc + Spring + mybatis(ibatis) (SSM)
- Spring Boot(下一代架構 微服務架構)
7. Spring
1. Spring的簡介
Spring是分層的JavaSE/EE full-stack(一站式) 輕量級開源架構
分層:
- SUN提供的JavaEE的三層結構:web層、業務層(service)、資料通路層(dao)(持久層,內建層)
- Struts2是web層基于MVC設計模式架構.
- Hibernate是持久的一個ORM的架構.
一站式:
- Spring對web層提供的解決方案 : Spring Mvc
- Spring對Service層提供的解決方案 : Spring
- Spring對Dao層提供的解決方案 : Jdbc Template
常用的解決方案:
1. web (Struts2 SpringMvc)
2.service(Spring)
3.dao(DBUtils HiberNate mybatis Jdbc Template)
建立Spring項目:
依賴關系:
2. Spring的核心
1. IOC(控制反轉)
把對象的建立權交給Spring容器
2. AOP(面向切面程式設計)
是面向對象的功能延伸.不是替換面向對象,是用來解決OOP(面向對象程式設計)中一些問題.
3. Spring的版本
spring3.x
spring4.x(推薦使用)
4. Spring的優點
-
友善解耦 簡化開發
把所有對象的建立交給Spring管理
-
支援Aop程式設計
解決在OOP中遇到的一些問題
- 聲明式事務的支援
-
友善調試程式
在spring中有專門的調試子產品Spring-Test
-
友善繼承各種優秀的架構
Spring對各種主流的架構都提供了支援
- Spring對一些比較難用的API都進行了封裝,友善了程式猿的使用(郵件 遠端調用....)
5. 日志架構
log4j:開源的優秀的日志架構
..........
日志門面:運作這些日志系統的
slf4j
logging (apache的日志門面)
Log log4j = Log log4j = LogFactory.getLog(TestLog.class);
log4j.info("info");
log4j.debug("debug");
log4j.error("error");
6. Spring的入門
建立實體類:
package com.ma.spring.demo01;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1. pom依賴
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
2. 建立log4j的配置檔案
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=debug, stdout
3. 建立Spring的配置檔案
在resources目錄下建立applicationContext.xml
引入XML的限制:
<?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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 把User交給Spring管理-->
<bean id = "user" class = "com.ma.spring.demo01.User"></bean>
</beans>
4. 使用ApplicationContext建立對象
@Test
public void test01(){
//1、建立Spring的工廠對象(BeanFactory ApplicationContext)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2、使用applicationContext.xml内部配置的bean來建立對象
User user = (User) applicationContext.getBean("user");
System.out.println(user);
}
7.ApplicationContext BeanFactory的差別
1.applicationContext繼承自BeanFactory
2.在老版本中Spring中使用BeanFactory,在新版本中使用ApplicationContext
3.BeanFactory會在調用getBean時執行個體化對象,applicationContext會在容器加載的時候執行個體化對象
8.bean中name和id的差別
1.name和id都是用來給Spring管理的對象命名的
2.id遵循的是xml規範(唯一)
3.name可以配置多個(name = “user1,use2,user3”)
4.name可以出現特殊字元,id不可以出現特殊字元
5.一般使用id屬性
9.屬性的注入(DI)
DI:依賴注入 : 在對象的建立過程中給屬性指派
1.按構造器注入
<!--使用構造器注入屬性-->
<constructor-arg name="age" value="21"></constructor-arg>
<constructor-arg name="name" value="小王"></constructor-arg>
2.按setter方法注入
<!--setter方法注入 property的name屬性值為:setter方法的名字的首字母小寫-->
<bean id = "user" class = "com.ma.spring.demo01.User">
<property name="age" value="20"></property>
<property name="name" value="小明"></property>
</bean>
開發過程中推薦使用setter方法注入
10.IOC和DI的差別
IOC : 把對象的建立權交給容器
DI : 建立對象時注入對象的屬性
11.Spring如何管理對象的建立
1、使用無參的構造器
<!--預設使用無參的構造器-->
<bean id = "user" class = "com.ma.spring.demo01.User">
</bean>
2、靜态工廠執行個體化
靜态工廠類
package com.ma.spring.demo01;
public class UserFactory {
public static User newInstance(){
return new User();
}
}
xml
<!--靜态工廠建立對象-->
<bean id = "user" class = "com.ma.spring.demo01.UserFactory" factory-method="newInstance"
</bean>
3、執行個體工廠建立對象
執行個體工廠類
package com.ma.spring.demo01;
public class UserFactory {
public User newInstance(){
return new User();
}
}
xml
!--執行個體工廠建立對象-->
<bean id = "userFactory" class="com.ma.spring.demo01.UserFactory"></bean>
<bean id="user" factory-bean="userFactory" factory-method="newInstance"></bean>
12.Bean的作用範圍
全局建立一個對象
<bean id = "user" class = "com.ma.spring.demo01.User" scope="singleton">
</bean>
調用一次對象建立一個
scope="prototype"
13.Bean的初始化和銷毀
package com.ma.spring.demo01;
public class User {
private Integer age;
private String name;
public User(){
System.out.println("構造方法......");
}
public void init(){
System.out.println("初始化方法......");
}
public void destory(){
System.out.println("銷毀方法......");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
xml
<bean id = "user" class = "com.ma.spring.demo01.User" scope="singleton" init-method="init" destroy-method="destory">
</bean>
容器建立時,會建立配置的Bean的對象,并且執行init()方法
//1、建立Spring的工廠對象(BeanFactory ApplicationContext)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2、使用applicationContext.xml内部配置的bean來建立對象
User user1 = (User) applicationContext.getBean("user");
User user2 = (User) applicationContext.getBean("user");
System.out.println(user1);
System.out.println(user2);
Spring容器銷毀的時候執行銷毀方法
applicationContext.close();
14.Bean的生命周期
- instantiate bean對象執行個體化(如果scope="singleton"時,在容器加載時建立執行個體)
- populate properties 封裝屬性(DI)
- 如果Bean實作BeanNameAware 執行 setBeanName
- 如果Bean實作BeanFactoryAware 或者 ApplicationContextAware 設定工廠 setBeanFactory 或者上下文對象 setApplicationContext
- 如果存在類實作 BeanPostProcessor(後處理Bean) ,執行postProcessBeforeInitialization(aop的底層)
- 如果Bean實作InitializingBean 執行 afterPropertiesSet
- 調用<bean init-method="init"> 指定初始化方法 init
- 如果存在類實作 BeanPostProcessor(處理Bean) ,執行postProcessAfterInitialization
- 執行業務處理
- 如果Bean實作 DisposableBean 執行 destroy
- 調用<bean destroy-method="customerDestroy"> 指定銷毀方法 customerDestroy
15.DI的複雜注入
1.普通的字面量的注入
<bean id = "user" class = "com.ma.spring.demo01.User">
<property name="age" value="20"></property>
<property name="name" value="小明"></property>
</bean>
2.對象注入
<bean id="user" class="com.ma.spring.demo01.User">
<property name="age" value="22"></property>
<property name="name" value="李四"></property>
</bean>
<bean id="orders" class="com.ma.spring.demo01.Orders">
<property name="user" ref="user"></property >
</bean>
測試類
package com.ma.spring.demo01;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class UserTest {
@Test
public void test01() {
//1、建立Spring的工廠對象(BeanFactory ApplicationContext)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2、使用applicationContext.xml内部配置的bean來建立對象
Orders orders = (Orders) applicationContext.getBean("orders");
System.out.println(orders);
//applicationContext.close();
}
@Test
public void test02() throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InstantiationException {
Class clazz = Class.forName("com.ma.spring.demo01.User");
//PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name",clazz);
//System.out.println(propertyDescriptor.getWriteMethod().getName());
Object obj = clazz.newInstance();
for(Method method : clazz.getMethods()){
if(method.getName().startsWith("set")){
System.out.println(method.getName());
}
}
}
}
3.Map的注入
<!--注入Map-->
<bean id="user" class="com.ma.spring.demo01.User">
<property name="age" value="30"></property>
<property name="name" value="傑克"></property>
<property name="map">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
<entry key="k3" value="v3"/>
</map>
</property>
</bean>
4.List的注入
<!--注入List-->
<bean id="user" class="com.ma.spring.demo01.User">
<property name="age" value="30"></property>
<property name="name" value="傑克"></property>
<property name="map">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
<entry key="k3" value="v3"/>
</map>
</property>
<property name="hobbies">
<list>
<value>Java</value>
<value>Python</value>
<value>PHP</value>
</list>
</property>
</bean>