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