Spring的扩展
Posted cgblpx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring的扩展相关的知识,希望对你有一定的参考价值。
文章目录
模拟SpringIoC的实现
概念
SpringIoC控制反转底层实现利用了java自身提供的反射技术来创建对象
Class.forName(classPath).newInstance();
通过这种方式,spring控制了对象的生命周期,可以随时自行增强对象,如DI依赖注入,如AOP,环绕通知在类创建前后增强功能,如Transaction事务加强等。
开发步骤
- 创建容器管理bean,并初始化容器-> [user,dept,hello]
- 创建spring容器,并初始化容器-> {hello=new Hello(),user=new Uer() }
- 提供getBean(),根据bean的名字,从spring容器中获取对应的对象
Bean.java
抽象Bean的定义,取代java中的Object,Spring框架中万物皆Bean。
package cn.tedu.design;
//模拟spring管理bean,存放bean
public class Bean {
private String name;//bean名字-> hello
private String path;//bean对应的类路径->cn.tedu.desing.Hello
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
SpringContext.java
逻辑复杂,IoC实现的核心,最关键点还是怎么创建对象实例:
package cn.tedu.design;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
//模拟spring框架,是spring的核心
//1,创建容器管理bean-> [user,dept,hello]
//2,创建spring容器-> {hello=new Hello(),user=new Uer() }
//3,getBean(),有就直接取出来,没有就创建并放入容器
public class SpringContext {
//1,创建容器管理bean-> [user,dept,hello]
private List<Bean> beanFactory = new ArrayList<>();
//初始化容器
public SpringContext() throws Exception {
//创建Bean,并加入容器中
Bean bean = new Bean();
bean.setName("hello");
bean.setPath("cn.tedu.pojo.Hello");
beanFactory.add(bean);
init();
}
//2,创建spring容器-> {hello=new Hello(),user=new Uer() } //并发安全的map
private final Map<String, Object> factoryBeanObject = new ConcurrentHashMap<>();
//初始化spring容器-> {hello=new Hello(),user=new Uer() }
public void init() throws Exception {
//遍历beanFactory,得到每个bean
for(Bean b : beanFactory) {
//map里的key
String key = b.getName();
//反射创建对象,作为value存入map
String path = b.getPath();
Object value = Class.forName(path).newInstance();
factoryBeanObject.put(key, value);
}
}
//3,getBean()有就直接取出来,没有就创建并放入容器
public Object getBean(String name) {
return factoryBeanObject.get(name);//去map里根据key找value
}
}
Hello.java
package spring;
public class Hello {
public void hi() {
System.out.println("hi springioc");
}
}
TestMyIoC.java
package cn.tedu.spring;
import cn.tedu.design.SpringContext;
import cn.tedu.pojo.Hello;
public class TestMyIOC {
public static void main(String[] args) throws Exception {
SpringContext spring = new SpringContext();
Hello o = (Hello)spring.getBean("hello");
System.out.println(o);//cn.tedu.pojo.Hello@6d06d69c
o.hi();
}
}
模拟SpringDI的底层实现
Student.java
package cn.tedu.designdi;
import org.springframework.stereotype.Component;
@Component
public class Student {
private String name="王一博";
@MyAutowired //di
private Teacher teacher;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\\'' +
", teacher=" + teacher +
'}';
}
}
Teacher.java
package cn.tedu.designdi;
import org.springframework.stereotype.Component;
@Component
public class Teacher {
private String name="皮皮霞";
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\\'' +
'}';
}
}
自定义注解
package cn.tedu.designdi;
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 MyAutowired {
String value() default "" ;
}
TestMyDI.java
package cn.tedu.designdi;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Field;
//有注解的属性就new
public class TestDI {
@Test
public void di() throws Exception{
//获取Student类里的属性,哪个属性有MyAutowired注解就给他new一个
Class s = Class.forName("cn.tedu.designdi.Student");
Object o = s.newInstance();
Field[] fs = s.getDeclaredFields();
for (Field f : fs) {
MyAutowired an = f.getAnnotation(MyAutowired.class);
if(an != null){
f.setAccessible(true);
f.set(o,new Teacher());
}
}
// Student{name='王一博', teacher=Teacher{name='皮皮霞'}}
System.out.println((Student)o);
}
}
Spring整合SpringMVC的项目实战
Spring用来管理项目中的所有Bean,需要使用注解@Component @Autowired @Service @Component等
Springmvc用来管理Controller层,需要使用的注解有@RestController @RequestMapping等
需求
访问链接: http://localhost:8080/car/get
得到JSON数据: {"name":"保时捷","color":"红色","price":641000.0}
项目结构
创建RunApp.java
package cn.tedu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class);
}
}
创建application.yml文件
server:
port: 8090
创建Car类
package cn.tedu.pojo;
import org.springframework.stereotype.Component;
@Component
public class Car {
private String name ;
private String color;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\\'' +
", color='" + color + '\\'' +
", price=" + price +
'}';
}
}
创建CarService接口
package cn.tedu.service;
import cn.tedu.pojo.Car;
public interface CarService {
Car get();
}
创建CarServiceImpl实现类
package cn.tedu.service;
import cn.tedu.pojo.Car;
import org.springframework.stereotype.Service;
@Service
public class CarServiceImpl implements CarService{
@Override
public Car get() {
Car c = new Car();
c.setName("保时捷");
c.setColor("红色");
c.setPrice(641000.0);
return c;
}
}
创建CarController类
package cn.tedu.controller;
import cn.tedu.pojo.Car;
import cn.tedu.service.CarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/car/")
public class CarController {
@Autowired
private CarService carService;
@RequestMapping("get")
public Car get(){
return carService.get();
}
}
测试
打开浏览器访问:http://localhost:8090/car/get
以上是关于Spring的扩展的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段
Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]
What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段
解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段