Spring

spring

spring是为了解决企业级应用开发的复杂性而创建的,简化开发 。

优点:

  • ·Spring是一个开源的免费的框架(容器)!

  • ·Spring是一个轻量级的、非入侵式的框架!

  • ·控制反转(IOC),面向切面编程(AOP)!

  • 支持事务的处理,对框架整合的支持!

    总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

1.ioc (控制反转)

1.了解由来

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kfoBYzSz-1603280894561)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\image-20200601001550528.png)]

1.常规调用,把userDao的实现类绑死了,这里是UserDaoImpl
public class UserServiceImpl implements UserService{
    UserDao userDao = new UserDaoImpl();//组合
    
    public void getUserDao() {
        userDao.getUser();//调用UserDaoImpl的getUser方法
    }
}
2.经过调整,实现控制权的反转
public class UserServiceImpl implements UserService{
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;//此是userDao是不确定的,由传参人决定其实体类对象
    }

    public void getUserDao() {
        userDao.getUser();//调用UserDao实现类的getUser方法,
                        // 由传进来的userDao决定,掌控权在传参人手里
    }
}
测试类:
public class MyTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();//创建UserServiceImpl对象,类型为接口
        //etUserDao为UserServiceImpl独有,故需要转型,然后传入参数
        ((UserServiceImpl)userService).setUserDao(new UserDaoMysqlImpl());
        //调用接口方法
        userService.getUser();
    }
}
总结:
  • 之前,程序是主动创建对象!座制权在程序猿手上!
  • 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象!

​ 这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!这是IOC的原型!

2. ioc本质

使用容器

ClassPathXmlApplicationContext

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

思考问题?
Hello对象是谁创建的?
hello 对象是由Spring创建的
Hello对象的属性是怎么设置的?
hello 对象的属性是由Spring容器设置的

这个过程就叫控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转:程序本身不创建对象,而变成被动的接收对象.
依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码.
OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的loC,一句话搞定:对象由Spring 来创建,管理,装配!

2.依赖注入

2.1构造函数的依赖注入

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>
2.1.1构造函数参数类型匹配 (不建议使用)

​ 在前面的场景中,如果您显式指定构造函数参数的类型,则容器可以使用类型匹配和简单类型。type属性。如下例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
2.1.2构造参数索引

​ 您可以使用index属性显式指定构造函数参数的索引,如下例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>
2.1.2构造函数参数名

​ 还可以使用构造函数参数名称进行值消歧,如下面的示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!

2.2set方式注入【重点】

依赖注入:set注入

  • 依赖:bean对象的创建依赖于容器!
  • 注入:bean对象中的所有属性,由容器来注入!

3.bean的自动装配

3.1使用注解实现自动装配

jdk1.5支持的注解,Spring2.5就支持支持注解了!

The introduction of annotation-based configuration raised the question of whether this approach is “better”
than XML.

要使用注解须知:

​ 1.导入约束

​ 2.配置注解的支持

<?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/>

</beans>
3.2使用注解开发
//相当于:<bean id="user" class="com.kuang.pojo.User"></bean>
//@Component 组件
@Component
public class User {

    //相当于:<property name="name" value="老王"></property>
    @Value("老王")
    private String name;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fQbqH50u-1603280894562)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\image-20200602004625592.png)]

小结:xml与注解:
  • xml更加万能,适用于任何场合!维护更加简单方便
  • 注解 不是自己类使用不了,维护相对复杂!

xml与注解最佳实践:

  • xml用来管理bean;
  • 注解只负责完成属性的注入;
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
    <!--指定要扫描的包,这个下的注解就会生效-->
    <context:component-scan base-package="com.kuang.pojo"/>
    <context:annotation-config/>

4.代理

1.静态代理

2.动态代理

//通用代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }
    //生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //处理代理类实例,并返回结果;
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(target, args);
        return result;
    }
}

接口:

public interface Rent {
    void rent();
}

真实类:

public class Host implements Rent{
    public void rent() {
        System.out.println("出租房子!");
    }
}

客户类+main方法:

public class Client {
    public static void main(String[] args) {
        //真实对象
        Rent rent = new Host();
        //代理对象,不存在
        ProxyInvocationHandler handler = new ProxyInvocationHandler();

        handler.setTarget(rent);//设置代理对象,传入真实对象

        //动态生成代理类
        Rent proxy = (Rent)handler.getProxy();
        //调用其方法
        proxy.rent();


    }
}

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

动态代理的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业
  • 公共也就就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!

5.AOP

1.什么是aop

2.aop在spring中的作用

3.使用spring实现aop

【重点】使用AOP织入,需要导入一个依赖包!

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

方式一:使用spring的API接口【主要springAPI接口实现】

方式二:自定义来实现AOP【主要是切面定义】

方式三:使用注解实现!

切入点表达式:

作用:对哪个类里面的哪个方法进行增强

语法结构:

execution([权限修饰符][返回值类型][类全路径][方法名称]([参数列表]))
例如:对com.kuang.dao.BookDao类里面的add进行增强
返回值类型 可以不写,权限修饰符可以用 * 表示所有
execution(* com.kuang.dao.BookDao.add(..))
如果式该类中的所有方法都增强的话 方法处用 * 代替,表示所有。

6.整合mybatis

1.mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
    <!--设置别名-->
    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>

</configuration>

2.spring-dao.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">
    <!--专注于操作数据库-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;useSSL=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!--使用 SqlSessionFactoryBean来创建 SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--绑定Mybatis配置文件,可以绑定也可以不绑定,建议绑定-->
        <property name="configLocation" value="mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/>
    </bean>

    <!--SqlSessionTemplate就是我们使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能使用构造器注入sqlSessionFactory,因为SqlSessionTemplate没有构造方法-->
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>


</beans>

3.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">

    <import resource="spring-dao.xml"/>

    <bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession" />
    </bean>
</beans>

4.UserMapperImpl

//这个类似乎就是以前的工具类MybatisDao,只不过现在由spring接管
public class UserMapperImpl implements UserMapper{
    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public List<User> selectUser() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser();

    }
}

5.MyTest

public class MyTest {
    @Test
    public void test() throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapperImpl.class);
        List<User> users = userMapper.selectUser();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

7.声明式事务

1.回顾事务:

  • 把一组业务当成一个业务来做,要么都成功,要么都失败!

  • 事务在项目中,十分重要,涉及数据的一致性问题,不能马虎!

  • 确保问政性和一致性;

事务ACID原则:

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能操作同一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中!

2.spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要在代码中,进行事务的管理

思考:

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况;
  • 如果我们不在spring中配置声明式事务,我们就要在代码中手动配置事务!
  • 事务在项目中十分重要,涉及数据的一致性和完整性问题,不容马虎!

ectUser();
for (User user : users) {
System.out.println(user);
}
}
}


## 7.声明式事务

### 1.回顾事务:

- 把一组业务当成一个业务来做,要么都成功,要么都失败!

- 事务在项目中,十分重要,涉及数据的一致性问题,不能马虎!

- 确保问政性和一致性;

  

事务ACID原则:

- 原子性
- 一致性
- 隔离性
  - 多个业务可能操作同一个资源,防止数据损坏
- 持久性
  - 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中!

### 2.spring中的事务管理

- 声明式事务:AOP
- 编程式事务:需要在代码中,进行事务的管理

思考:

为什么需要事务?

- 如果不配置事务,可能存在数据提交不一致的情况;
- 如果我们不在spring中配置声明式事务,我们就要在代码中手动配置事务!
- 事务在项目中十分重要,涉及数据的一致性和完整性问题,不容马虎!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5k7gIqo6-1603280894562)(C:\Users\Admin\AppData\Roaming\Typora\typora-user-images\image-20200604122958318.png)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值