1 spring概述

spring是分层的JavaSE及JavaEE利用于全栈的轻量级开源框架,以 IoC (Inverse Of Control:管制反转/反转管制)和 AOP (Aspact Oriented Programming:面向切面编程)为外围,提供了体现层SpringMVC和长久层Spring JDBC以及业务层事务管理等泛滥模块的企业级利用技术,还能整合开源世界中泛滥 驰名的第三方框架和类库,逐步成为应用多的JavaEE企业应用开源框架。

spring框架次要用来解决业务间的逻辑,如账号注册时的用户名判断等等。

spring框架其中最外围的是:IoC管制反转、DI依赖注入、SpringAOP面向切面编程、事务管制。

1.1 spring的架构:

Spring 初的指标就是要整合所有优良资源,而后对外提供一个对立的服务。 Spring 模块构建在外围容器之上,外围容器定义了创立、配置和治理 bean 的形式, 如下图所示:

组成 Spring 框架的每个模块(或组件)都能够独自存在,或者与其余一个或多 个模块联结实现。每个模块的性能如下:

2 IoC+DI

IoC是设计思维,IoC有三个外围:BeanFactory、反射、DI。BeanFactory利用反射实现对象的创立,DI实现对象关系治理。

2.1 IoC管制反转

IOC(Inverse Of Control)管制反转,即,把创建对象的权力交给框架。
也就是指将对象的创立、对象的存储、对象的治理交给了spring容器。

2.1.1 spring中的IoC的实现

第一步:创立maven我的项目spring

第二步:在pom文件中增加junit、spring依赖

        <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");}

2.1.2 springboot整合spring中的IoC的实现

实现类上加注解@service,将工夫类交给spring框架治理,放入bean容器。
利用@Autowired注解,由框架进行对象赋值。

第一步:创立UserService

package com.tedu.springioc01.service;public interface UserService {    public String register();}

第二步:创立UserServiceImpl实现UserService

package com.tedu.springioc01.service;import org.springframework.stereotype.Service;//这是一个业务层类,由框架创建对象@Servicepublic class UserServiceImpl implements UserService{    @Override    public String register() {        //判断用户名是否注册过        return "注册胜利";            }}

第三步:创立UserController

@RestControllerpublic class UserController {//由框架给userService赋值,不必程序员创立    @Autowired    UserService userService;    @RequestMapping("/register")    public String register() {        String result=userService.register();        return result;    }}

2.1.3 springboot整合spring中的IoC的底层实现


第一步:创立注解自定义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框架

  • 创立LoadObject()容器。
  • 在autowiredProcess()中通过反射解决autowired,给属性赋值。
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);        }    }

2.2 DI依赖注入

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面向切面编程,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实现

利用aop实现查看业务层办法的执行工夫。

第一步:创立启动类Springaop06AopApplication

package com.tedu.springaop06_aop;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic 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;@RestControllerpublic class UserController {    //调用业务层,从spring 容器中得对象    @Autowired //管制反转ioc    UserService userService;    @RequestMapping("/register")    public String register(String username) {        //调用业务层        String result = userService.register(username);        return result;    }}