spring

168 阅读4分钟

基础

框架:一种规范,封装了特定的处理流程和控制逻辑

POJO(Plain Ordinary Java Object):简单无规则 Java 对象

面向接口编程:接口与实现分离,相当与 父类 a = new 子类

自动装配www.yiibai.com/spring/spri…

Bean管理的注解实现及例子

IOC

spring 4.x可以脱离xml,使用注解

what

IOC是Inversion of Control的缩写,中文翻译为控制反转。

控制:一个应用程序在OOP的编程思想下是N个对象协同工作的,在一个对象需要另一个对象时我们往往会在这个对象的方法里new一个别的对象,或者使用一个已经new好的对象,此时的调用或创建对象的控制权在自己手上。在对象A的方法内调用对象B,我们可以说A和B是耦合的。

控制反转:就是控制变为被控制。当对象A需要调用对象B时,不需要他主动创建对象B,而是一个叫做IOC的容器去创建一个对象B注入到对象A中,控制权交给了这个容器,所以叫控制反转。

作用:通过容器解决对象间的耦合。

实现方式: IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

所有的IOC容器都需要实现BeanFactory接口,大部分spring ioc容器实现的是ApplicationContext接口

例子

例子1

写个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-3.0.xsd">

           <bean id="hello" class="com.spring.hello.HelloSpringImpl"/>
</beans>

使用IOC容器

package com.spring.hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestHello {

    public static void  main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
        HelloSpring hello = context.getBean("hello",HelloSpring.class);
        hello.sayHello();
    }
}
例子2

使用注解@Component

package com.spring.hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("hello")
public class HelloSpringImpl implements HelloSpring{


    @Override
    public void sayHello() {
        System.out.println("i am like");

    }

}

注入 @Autowired

@Autowired
private HelloSpringImpl helloSpringImpl;

关于scope

  1. Spring中的bean默认都是单例的
  2. 对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Sevlet线程来处理请求,引入Spring框架之后,每个Action都是单例的,那么对于Spring托管的单例Service Bean,如何保证其安全呢? Spring的单例是基于BeanFactory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于 JVM,每个 JVM 内只有一个实例。

AOP(面向切面编程)

what

  1. 编程范式
  2. 将通用逻辑从业务逻辑中分离出来(事物管理,日志)

例子

例子1
依赖(pom.xml)
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
文件
@Aspect
@Component
public class HttpAspect {

    private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);


    @Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log() {
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        Gson gson = new Gson();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //url
        logger.info("url={}", request.getRequestURL());

        //method
        logger.info("method={}", request.getMethod());

        //ip
        logger.info("ip={}", request.getRemoteAddr());

        //类方法
        logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

        //参数
        logger.info("args={}", joinPoint.getArgs());
    }

    @After("log()")
    public void doAfter() {
        logger.info("222222222222");
    }

    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        logger.info("response={}", object.toString());
    }

}

关键注释:@Aspect

例子2

参考文章:zhuanlan.zhihu.com/p/83004139 参考文章:zhuanlan.zhihu.com/p/21273202

日志

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
public class HelloController {
    @Autowired
    public LimitConfig limitConfig;
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
    @GetMapping("/say")
    public String say(String gg){
        logger.info("sdfsdfsdf");
        return "id    " + limitConfig.getDescription();
    }
}

和异常

测试

一般的测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class GirlServiceTest {

    @Autowired
    private GirlService girlService;

    @Test
    public void findOneTest() {
        Girl girl = girlService.findOne(73);
        Assert.assertEquals(new Integer(13), girl.getAge());
    }
}

对controller层的测试

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GirlControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void girlList() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/girls"))
                .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(MockMvcResultMatchers.content().string("abc"));
    }

}

注释记录

@Bean

用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。

    @Bean
    public   BeanTest  getBean(){
        BeanTest bean = new  BeanTest();
        System.out.println("调用方法:"+bean);
        return bean;
    }