spring是分層的JavaSE及JavaEE應用於全棧的輕量級開源框架,以 IoC (Inverse Of Control:控制反轉/反轉控制)和 AOP (Aspact Oriented Programming:面向切面編程)爲核心,提供了表現層SpringMVC和持久層Spring JDBC以及業務層事務管理等衆多模塊的企業級應用技術,還能整合開源世界中衆多 著名的第三方框架和類庫,逐漸成爲使用多的JavaEE企業應用開源框架。java
spring框架主要用來處理業務間的邏輯,如帳號註冊時的用戶名判斷等等。程序員
spring框架其中最核心的是:IoC控制反轉、DI依賴注入、SpringAOP面向切面編程、事務控制。web
Spring 初的目標就是要整合一切優秀資源,而後對外提供一個統一的服務。 Spring 模塊構建在覈心容器之上,核心容器定義了建立、配置和管理 bean 的方式, 以下圖所示:
組成 Spring 框架的每一個模塊(或組件)均可以單獨存在,或者與其餘一個或多 個模塊聯合實現。每一個模塊的功能以下:
spring
IoC是設計思想,IoC有三個核心:BeanFactory、反射、DI。BeanFactory利用反射實現對象的建立,DI實現對象關係管理。編程
IOC(Inverse Of Control)控制反轉,即,把建立對象的權利交給框架。
也就是指將對象的建立、對象的存儲、對象的管理交給了spring容器。
瀏覽器
第一步:建立maven項目spring
第二步:在pom文件中添加junit、spring依賴springboot
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.3.RELEASE</version> </dependency>
第三步:在工程的src/main/resources目錄下,建立applicationContext.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"> <!-- 將EmpService接口的實現類做爲bean註冊到spring容器中 即 讓spring容器建立該類的實例(對象) 若是註冊的類有父接口,id值一般是接口名(首字母小寫) 若是註冊的類沒有父接口,id值一般爲類名(首字母小寫) --> <bean id="empService" class="com.tedu.service.EmpServiceImpl02"></bean> <!-- 將User類做爲bean註冊到spring容器中, 也就是由spring容器 負責建立該類的實例 scope="singleton|prototype",默認值是singleton,表示單實例 若是將scope值改成prototype,則每次都會建立新的User實例,也就 是多實例 --> <!-- (2)構造方法注入 --> <bean id="user" class="com.tedu.pojo.User"> <constructor-arg name="name" value="馬雲"/> <constructor-arg name="age" value="30"/> <constructor-arg name="info" ref="userInfo"/> </bean> <!-- 將UserInfo類做爲bean註冊到spring容器中 --> <bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean> </beans>
第四步:建立測試類TestSpring,進行測試架構
package com.tedu; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.tedu.pojo.User; public class TestSpring { //獲取spring的容器對象 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); @Test public void testIoC() { //經過spring容器對象獲取User類的實例 User u1 = (User)ac.getBean("user"); }
實現類上加註解@service,將時間類交給spring框架管理,放入bean容器。
利用@Autowired註解,由框架進行對象賦值。mvc
第一步:建立UserService
package com.tedu.springioc01.service; public interface UserService { public String register(); }
第二步:建立UserServiceImpl實現UserService
package com.tedu.springioc01.service; import org.springframework.stereotype.Service; //這是一個業務層類,由框架建立對象 @Service public class UserServiceImpl implements UserService{ @Override public String register() { //判斷用戶名是否註冊過 return "註冊成功"; } }
第三步:建立UserController
@RestController public class UserController { //由框架給userService賦值,不用程序員建立 @Autowired UserService userService; @RequestMapping("/register") public String register() { String result=userService.register(); return result; } }
第一步:建立註解自定義Autowired
package org.spring.ioc; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //自動裝配,給屬性自動賦值 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Autowired { }
第二步:建立UserServiceImpl
package com.tedu; //業務層類 public class UserServiceImpl { }
第三步:建立UserController
package com.tedu; //表現層 import org.spring.ioc.Autowired; public class UserController { //須要業務層對象 @Autowired UserServiceImpl userServiceImpl; }
第四步:建立IOCMain,模擬spring框架
package org.spring.ioc; //模擬spring 框架 import java.awt.Container; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Set; import com.tedu.UserController; import com.tedu.UserServiceImpl; public class IOCMain { //放對象的容器 public static HashMap<String, Object> container=new HashMap<String, Object>(); //userServiceImpl,object //userController,UserController的對象 public static void main(String[] args) throws Throwable { //加載對象到容器中 loadObject(); //處理autowired,給屬性賦值 autowiredProcess(); //測試UserController的userServiceImpl屬性是否有值 //從容器中找對象 UserController userController=(UserController) container.get("userController"); //打印對象的屬性 System.out.println(userController.toString()); } private static void autowiredProcess() throws Throwable{ //遍歷hashMap的key Set<String> keySet=container.keySet();//獲得集合 for (String name : keySet) { //根據key獲得對象 Object object=container.get(name); //根據對象獲得類對象 Class clazz=object.getClass(); //根據類對象獲得全部屬性 Field[] fields=clazz.getDeclaredFields(); //遍歷全部屬性 for (Field field : fields) { //判斷屬性是否加了autowired Autowired autowired=field.getAnnotation(Autowired.class); //若是加了,給容器中找到對象,賦值 if (autowired !=null) { //field.getName() userServiceImpl Object value=container.get(field.getName()); field.setAccessible(true); //建立對象 field.set(object, value); } } } } private static void loadObject() { UserController userController=new UserController(); container.put("userController",userController); UserServiceImpl userServiceImpl=new UserServiceImpl(); container.put("userServiceImpl",userServiceImpl); } }
Set方法注入:
<bean id="user" class="com.tedu.spring.User"> <property name="name" value="韓少雲"/>:調用setName方法給name屬性賦值爲韓少雲 <property name="age" value="20"/>:調用setAge方法給age屬性賦值爲20 <property name="info" ref="userInfo"/> </bean> <!--調用setInfo方法給info屬性賦值爲UserInfo類型的對象 上面的ref屬性指向的是,在獲取UserInfo類的對象時bean標籤的id值-->
構造方法注入:
<bean id="user" class="com.tedu.pojo.User"> <constructor-arg name="name" value="馬雲"/> <constructor-arg name="age" value="30"/> <constructor-arg name="info" ref="userInfo"/> </bean>
註解@Autowired注入
AOP面向切面編程,AOP是對動態代理的封裝。
切面類=切入點(ponitcut())+通知方法(@Around+@Before+@AfterReturning+@AfterThrowing)
第一步:建立接口IDAO
public interface IDAO { public void insert(); }
第二步:建立實現類UserDao實現IDAO
//目標類 public class UserDAO implements IDAO { @Override public void insert() { System.out.println("目標類UserDAO 的核心代碼 insert"); } }
第三步:建立代理類Proxy並添加業務功能
//代理類的方法必須和目標類的方法一致 public class Proxy implements IDAO { IDAO target; public Proxy(IDAO target) { this.target = target; } @Override public void insert() { long startTime = System.nanoTime(); target.insert(); long endTime = System.nanoTime(); System.out.println("insert佔用的時間=" + (endTime - startTime)); } }
第四步:測試靜態代理
public class TestProxy { public static void main(String[] args){ //建立目標對象 IDAO userDAO=new UserDAO(); //獲得代理對象 Proxy userDAOproxy=new Proxy(userDAO); //調用代理的方法 userDAOproxy.insert(); } }
第一步:建立IDAO接口
package springaop04_javaDynamicProxy; public interface IDAO { public String select(String username); }
第二步:建立實現類UserDAO實現IDAO
package springaop04_javaDynamicProxy; public class UserDAO implements IDAO{ @Override public String select(String username) { return "目標類UserDAO.select()"+username; } }
第三步:建立TestProxy類,實現動態代理
package springaop04_javaDynamicProxy; //jdk的動態代理 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class TestProxy { public static void main(String[] args) { UserDAO target=new UserDAO(); //根據target獲得類對象 Object proxyObject=getProxy(target); //獲得代理對象的類對象 Class clazz = proxyObject.getClass(); //經過類對象獲得類型 System.out.println(clazz.getName());//這個類是咱們寫的嗎?com.sun.proxy.$Proxy0 //經過類對象獲得類的方法 Method[] methods=clazz.getDeclaredMethods(); for (Method method : methods) { //select(){調用invocationHandler.invoke(調用invocationHandler.invoke())} System.out.println(" "+method.getName()); } //類型轉換 IDAO userIdao=(IDAO) proxyObject; //java運行時生成類$Proxy0.select(){調用invocationHandler.invoke()} userIdao.select("admin"); } private static Object getProxy(IDAO target) { //獲得目標類的全部接口 Class[] interfaces=target.getClass().getInterfaces(); //獲得類加載器 ClassLoader classLoader = target.getClass().getClassLoader(); //建立invocationHandler的對象 MyHandler myHandler = new MyHandler(target); //調用java生成代理對象 Object proxyObject=Proxy.newProxyInstance (classLoader, interfaces, myHandler); return proxyObject; } //1,建立InvocatonHandler的實現類 static class MyHandler implements InvocationHandler{ IDAO target; //經過構造方法接收目標類對象 public MyHandler(IDAO target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke"); //執行擴展功能 long startTime = System.nanoTime(); //調用目標類 Object result = method.invoke(target, args); return null; } } }
利用aop實現查看業務層方法的執行時間。
第一步:建立啓動類Springaop06AopApplication
package com.tedu.springaop06_aop; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Springaop06AopApplication { public static void main(String[] args) { SpringApplication.run(Springaop06AopApplication.class, args); } }
第二步:建立接口UserService
package com.tedu.springaop06_aop.service; public interface UserService { public String register(String username); }
第三步:建立實現類UserServiceImpl實現Userservice
package com.tedu.springaop06_aop.service; import org.springframework.stereotype.Service; //業務層實現類 @Service//讓spring建立一個對象,對象放在spring的容器中 public class UserServiceImpl implements UserService{ @Override public String register(String username) { return username+"註冊成功了"; } }
第四步:建立切面類TimeAspect,實現無侵入式編程
package com.tedu.springaop06_aop.service; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; //切面類:執行擴展功能,實現無侵入式編碼 @Component//組件,與@controller,@service功能同樣,框架會自動建立對象 @Aspect//這個類是個切面,在執行業務層方法以前或以後執行切面 public class TimeAspect { long startTime;//業務層方法開始時間 //切面像springmvc中的interceptor //.pathPattern(/order,/cart) //設置在運行哪些業務層類哪些方法時執行切面TimeAspect //pointcut:切入點,設置TimeAspect執行的時機 //execution:執行 //第一個*表明的是類 //第二個*表明的是類中的全部方法 //(..)表明的是方法的參數能夠是任何類型 //public * 表明方法的返回類型是任何類型 //註解中定義屬性 value() //aop框架 遍歷方法找@PointCut註解 @Pointcut("execution(public * com.tedu.springaop06_aop.service.*.*(..))") public void aopPointCut() { } //得起始時間 @Before("aopPointCut()")//在目標方法register以前執行 public void getStartTime() { startTime=System.nanoTime(); } //得結束時間 @After("aopPointCut()")//在目標方法register之和執行 public void getEndTime() { long endTime=System.nanoTime(); System.out.println("業務層方法執行的時間:"+(endTime-startTime)); //關閉服務器,重啓,瀏覽器發請求 //console中查看日誌 } }
第五步:建立UserController,調用業務層代碼
package com.tedu.springaop06_aop.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.tedu.springaop06_aop.service.UserService; @RestController public class UserController { //調用業務層,從spring 容器中得對象 @Autowired //控制反轉ioc UserService userService; @RequestMapping("/register") public String register(String username) { //調用業務層 String result = userService.register(username); return result; } }