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;
//这是一个业务层类,由框架创建对象
@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;
}
}
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;
@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;
}
}
发表回复