Spring简单笔记

Spring 5.x版本

001、依赖包

Spring的各包之间相互依赖,导入这一个包就可以包Spring的基本几个包同时引入。

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

002、控制反转/依赖注入

这是Spring的重点思想,ioc/dl,降低耦合度。

简单来说就是在一个项目中使用的类,不需要手动的new出来,通过Spring中的IOC容器来帮我们创建。

Spring早前的版本需要通过配置文件管理,后期使用纯注解就可以驱动。

这个IOC容器可以有很多形式,如BeanFactory,ApplicationContext等。

ApplicationContext应用上下文,这是最常用的容器。

1、ApplicatContext

ApplicatContext是一个IOC容器,我们编写好的类可以通过ApplicationContext进行存入获取等。

ApplicationContext是一个接口,下面有很多实现类,如ClassPathXmlApplicationContext、

FileSystemXmlApplicationContext、AnnotationConfigApplicationContext

通过配置文件的方式测试一下:

User类

package pojo;


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

public class User {

    private Integer id;
    private String name;
    private String gender;
    private String desc;

    public User() {
    }

    public User(Integer id, String name, String gender, String desc) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.desc = desc;
    }


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

resource.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="user" class="pojo.User">
       <constructor-arg index="0" value="301001800"/>
       <constructor-arg index="1" value="zhangsan"/>
       <constructor-arg index="2" value="female"/>
       <constructor-arg index="3" value="zhangsan is a student which learn cs"/>

    </bean>

</beans>

测试类:

通过ClassPathXmlApplicationContext拿到数据:

FileSystemXmlApplicationContext也可以,最好标明绝对路径。

 	ApplicationContext context;

    @Before
    public void load(){
        context=new ClassPathXmlApplicationContext("resource.xml");
    }

    @Test
    public void test(){
        User user = context.getBean("user", User.class);
     
        System.out.println(user);

    }

也可以通过注解扫描的方式获取bean.

User类

在User上添加注解。

@Component("super_user")
public class User {

    @Value("45616185")
    private Integer id;
   .....
}

servicel.xml

在servicel.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--注解驱动 -->
    <context:annotation-config/>
    <context:component-scan base-package="pojo"/>

</beans>

测试类,此时的测试类两个都可以获取到bean.

    ApplicationContext context;

    @Before
    public void load(){
        context=new ClassPathXmlApplicationContext("resource.xml","service.xml");
    }

    @Test
    public void test(){
        User user = context.getBean("user", User.class);
        User user2 = context.getBean("super_user", User.class);
        System.out.println(user +" \n"+user2);

    }
User{id=45616185, name='zhangsan', gender='female', desc='zhangsan is a student which learn cs'} 
User{id=45616185, name='null', gender='null', desc='null'}

2、纯注解驱动

此时不需要各种配置文件,只要使用JavaConfig即可。

通过AnnotationConfigApplicationContext拿到数据。

//声明是一个配置类
@Configuration
public class MyConfig {

    //获取一个bean
    @Bean("a_user")
    public User user(){
        return new User(45484154,"lisi","female","He is man");
    }
}

此时测试可以:

@Test
public void test01(){
    ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = context.getBean("a_user",User.class);
        System.out.println(user);
    }

//User{id=45616185, name='lisi', gender='female', desc='He is man'}

javaConfig可以代替所有xml文件的功能,如使用注解扫描功能:

@Configuration
@ComponentScan("pojo")
public class MyConfig {

    //获取一个bean
    @Bean("a_user")
    public User user(){
        return new User(45484154,"lisi","female","He is man");
    }
}

此时之前注解里的bean也可以获取。

 @Test
public void test01(){
    ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        User user = context.getBean("a_user",User.class);
        User s_user = context.getBean("super_user",User.class);
        System.out.println(user+"\n"+s_user);
    }

User{id=45616185, name='lisi', gender='female', desc='He is man'}
User{id=45616185, name='null', gender='null', desc='null'}

3、AutoWired

自动装载。

@Component
public class UserService {

    //将id=user的bean装入
    @Autowired
    User user;

    public void printUser(){
        System.out.println(user);
    }


}


//全局配置中加入被扫描的包
<context:component-scan base-package="service"/>

//此时已经可以调用该bean
UserService bean = context.getBean(UserService.class);
bean.printUser();

003、SpringAop

1、aop概念

aop面向切面编程,其实是一种面向对象的变种,面向对象通过继承能够使用父类的功能,但是会造成耦合。

面向切面则不会,同样增强了类的功能,面向切面是横向扩展的。

ApringAop底层使用代理模式。

SpringAop是Spring的另一大重点,用于帮助实现Aop.

1、横切关注点

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

2、切面(aspect)

类是对物体特征的抽象,切面就是对横切关注点的抽象

3、连接点(joinpoint)

被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

4、切入点(pointcut)

对连接点进行拦截的定义

5、通知(advice)

所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

6、目标对象

代理的目标对象

7、织入(weave)

将切面应用到目标对象并导致代理对象创建的过程

8、引入(introduction)

在这里插入图片描述

2、xml配置Aop

Aop需要相对的包:

<dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

首先需要提个切面类:

package aop;

import java.util.Date;

public class TimeLogHander {
    
    public void printLog() {
        System.out.println(new Date());
    }


    public void before(){
        System.out.print("before advice: ");
        printLog();
    }


    public void after(){
        System.out.print("after advice: ");
        printLog();
    }

}


一个被增强类:

package aop;

public class Work {

    public Work() {
    }


    public void preWork(){
        System.out.println("prework...");
    }

    public void overWork(){
        System.out.println("overwork....");
    }

    public void workIng(){
        System.out.println("working.....");
    }
}


使用aop.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

        <bean id="timeLogHander" class="aop.TimeLogHander"/>
        <bean id="work" class="aop.Work"/>

       	<aop:config>
            <aop:aspect id="timeLog" ref="timeLogHander">
                <aop:pointcut id="time" expression="execution(* aop.Work.*(..))"/>
                <aop:before method="before" pointcut-ref="time"/>
                <aop:after method="after" pointcut-ref="time"/>
            </aop:aspect>
        </aop:config>
</beans>

测试一下:

public class AopTest {
    ApplicationContext context;

    @Before
    public void pre(){
        context=new ClassPathXmlApplicationContext("aop.xml");
    }

    @Test
    public void test(){
        final Work work = context.getBean("work", Work.class);
        work.preWork();
        work.workIng();
        work.overWork();
    }
}


//结果符合预期
before advice: Mon Jun 08 00:48:26 CST 2020
prework...
after advice: Mon Jun 08 00:48:26 CST 2020
before advice: Mon Jun 08 00:48:26 CST 2020
working.....
after advice: Mon Jun 08 00:48:26 CST 2020
before advice: Mon Jun 08 00:48:26 CST 2020
overwork....
after advice: Mon Jun 08 00:48:26 CST 2020

3、注解驱动

使用注解的方式也可以,或者和xml配合。

这里使用完全注解驱动,不再使用xml。

配置类:

@Configuration
@ComponentScan("aop")
@EnableAspectJAutoProxy
public class AopConfig {

    @Bean
    public Work work(){
        return new Work();

    }
    @Bean
    public TimeLogHander timeLogHander(){
        return  new TimeLogHander();
    }
}

切面类:

注意这里的注解是aop包下的:

@Aspect
public class TimeLogHander{
    @Pointcut("execution(* aop.Work.*(..))")
    public void printLog() {
        System.out.println(new Date());
    }

    @Before("printLog()")
    public void before(){
        System.out.print("before advice: ");
        printLog();
    }


    @After("printLog()")
    public void after(){
        System.out.print("after advice: ");
        printLog();
    }

}


测试类:

public class AopConfigTest {
    ApplicationContext context;

    @Before
    public void load(){
        context=new AnnotationConfigApplicationContext(AopConfig.class);
    }

    @Test
    public void test(){
        final Work work = context.getBean(Work.class);

        work.preWork();

        work.workIng();
        work.overWork();
    }
}


posted @ 2020-12-28 10:00  cgl_dong  阅读(52)  评论(0编辑  收藏  举报