Spring5

总结:

1、spring就是一个轻量级的控制反转(IOC)和面相切面(AOP)编程的框架
2、IOC,总结一句话就是对象由spring来创建、管理、装配,其实现方法是依赖注入
3、实现IOC的三种方式:
	application.xml配置文件
	注解方式:<context:annotation-config/>
	java的Configuration(完全舍弃xml文件)
	最佳搭配方式:xml负责管理bean,注解负责属性的自动装配
4、@Autowired 是spring的注解 自动装配、@Resource 是java的注解 自动装配
5、AOP切面实现方式:标签<aop>
	方式一:Spring内置的AOP接口实现before、after两个接口的类,将类配置在切面中
	方式二:自定义类,在类中自定义before、after方法,配置在切面上
	方式三:在自定义类上加@Aspect,定义这是一个切面,在类中的方法上加注解@Before、@After定义这些方法是切面里面的方法
6、声明式事务:标签<tx>
	配置<tx>事务,声明方法将事务织入切面

定义:spring就是一个轻量级的控制反转(IOC)和面相切面(AOP)编程的框架

IOC(Sping核心)

Inversion of controller 控制反转

控制反转是一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式。

在spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection DI)

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身创建的,使用spring后是由spring创建的

反转:程序本身不创建对象,而是被动的接收对象

 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml")

注:当加载了xml文件获取到ioc容器对象context的时候,容器内就已经生成了各个对象

依赖注入:就是利用set方法注入的 (property属性的值由对象的set方法注入)

IOC是一种编程思想,由主动的编程编程被动的接受

所谓的IOC,总结一句话就是对象由spring来创建、管理、装配

实现IOC的三种方式

  1. application.xml配置文件
  2. 注解方式
  3. java的Configuration(完全舍弃xml文件)
    最佳搭配方式:xml负责管理bean,注解负责属性的自动装配

1、xml配置文件实现IOC

使用ClassPathXmlApplicationContext对象加载xml文件获取IOC容器

public class UserController {
    public static void main(String[] args) {
    	//当xml文件被加载之后,所有管理的对象就已经初始化了
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserServiceImpl bean = (UserServiceImpl)context.getBean("userServiceImpl");
        System.out.println(bean.getUser());
    }
}

属性通过set赋值

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

   <!--使用spring来创建对象-->
    <bean id="hello" class="pojo.Hello">
        <property name="str" value="wanghan"/>
    </bean>
    
</beans>

属性通过构造方法赋值

	<bean id="hello" class="pojo.Hello">
        <constructor-arg name="name" value="wnaghan"/>
    </bean>

依赖注入

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

各种属性配置方式:普通类型、数组、map、list、properties、set等数据类型

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- properties类型数据 -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- list -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- map -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- set -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
     <!-- 数组 -->
    <property name="books">
            <array>
                <value>三国演义</value>
                <value>水浒传</value>
            </array>
        </property>
</bean>

p命名空间 (set属性注入)

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
      https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean name="john-classic" class="com.example.Person">
      <property name="name" value="John Doe"/>
      <property name="spouse" ref="jane"/>
  </bean>

  <bean name="john-modern"
      class="com.example.Person"
      p:name="John Doe"
      p:spouse-ref="jane"/>

  <bean name="jane" class="com.example.Person">
      <property name="name" value="Jane Doe"/>
  </bean>
</beans>

c命名空间 (构造器注入)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>

    <!-- traditional declaration with optional argument names -->
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg name="thingTwo" ref="beanTwo"/>
        <constructor-arg name="thingThree" ref="beanThree"/>
        <constructor-arg name="email" value="something@somewhere.com"/>
    </bean>

    <!-- c-namespace declaration with argument names -->
    <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
        c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>
</beans>

注意:p命名空间和c命名空间都不能直接使用,需要导入c和p得约束文件

xmlns:c="http://www.springframework.org/schema/p
xmlns:c="http://www.springframework.org/schema/c

bean作用域

在这里插入图片描述
在这里插入图片描述

  1. singleton 单例模式(spring默认机制):只生成一个对象
  2. prototype 原型模式:生成多个对象
  3. 其余得request、session、application只有在web开发中才能使用到

bean的自动装配

  • 自动装配是Spring满足bean依赖的一种方式
  • spring会在上下文中自动寻找,并自动给bean装配属性
byName在这里插入图片描述
byType

在这里插入图片描述

2、注解方式实现IOC

使用注解的前提

  1. 导入AOP的依赖包
    在这里插入图片描述

  2. 在application.xml中导入约束文件
    在这里插入图片描述

  3. 开启注解和组件包扫描

<--开启注解-->
<context:annotation-config/>
<--使用@Component将类配置到IOC容器中-->
<context:component-scan base-package="com.kayak.pojo"/>

注解说明

  • @Autowired 是spring的注解 自动装配
    通过byType方式实现,如果类型不唯一,则需要通过 @Qualifier来指定id名称来实现
  • @Resource 是java的注解 自动装配
    通过byname方式,如果名字找不到,则通过bytype方式实现
  • @Component:组件,放在类上,说明这个类被spring管理了,就是bean!需要在xml中配置组件扫描包的路径
    在这里插入图片描述
 <context:component-scan base-package="pojo"/>
  • @Scop:作用域@Scop(“singleton”)或者prototype
	@Autowired
    @Qualifier(value = "dog")  //可以配置不同的id名称
    private Dog dog;
    @Resource(name = "cat")  //可以配置不同的id名称
    private Cat cat;
@Component
public class Dog {
    public void  shout(){
        System.out.println("汪");
    }
}

3、使用java配置spring实现IOC

使用AnnotationConfigApplicationContext对象加载xml文件获取IOC容器
我们现在 要完全不使用xml配置了,全权交给java来配置

@Configuration
@Import(MyConfiguration2.class) //合并另一个配置类
public class MyConfiguration {

    @Bean
    public StringStore stringStore() {
        return new StringStore();
    }

    @Bean
    public IntegerStore integerStore() {
        return new IntegerStore();
    }
}
public class MyTest {
    public static void main(String[] args) {
		//使用AnnotationConfigApplicationContext对象加载xml文件获取IOC容器
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        People people = context.getBean("people", People.class);
        people.getCat().shout();
        people.getDog().shout();

    }
}

代理模式

springAOP的底层就是代理模式

代理模式的分类:

1、静态代理

代理模式的好处:

  1. 可以使真实角色的操作更加纯粹,不用去关注一些公共业务
  2. 公共业务交给代理角色
  3. 公共业务发生拓展时,方便集中管理(可以在不改变原有代码的基础上,增加新的业务)

静态代理模式的缺点:
一种真实角色就会产生一种代理角色,代码量会翻倍,静态代理只能代理一个接口
(例如房屋中介,只代理房东租房,不做婚介)

代码步骤

接口(租房)

//租房接口
public interface Rent {
    void rent();
}

真实角色(房东)

public class Host implements Rent {
    public void rent() {
        System.out.println("我是房东,我要出租房子");
    }
}

代理角色(中介)

public class Proxy implements Rent {
    //房东Host实现租房的接口
    //租房的接口
    private Rent rent;
    public Proxy() {
    }
    public Proxy(Rent rent) {
        this.rent = rent;
    }
    public void rent() {
        rent.rent();
    }
    //属于公共事务,交由代理对象办理,公共事务变更时,代码更易于管理
    public void payServicefee(){
        System.out.println("交物业费");
    }
}

客户访问(客户)

//客户租房
public class Client {
    public static void main(String[] args) {
    	//host房东
        Host host = new Host();
        //找代理对象,代理对象有参构造传入房东,房东出租房子
        Proxy proxy = new Proxy(host);
        proxy.rent();
        //执行代理对象中的公共事务方法
        proxy.payServicefee();
    }
}

代理模式的理解
在这里插入图片描述

2、动态代理(反射实现)

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的
  • 动态代理分为两大类:
    1、基于接口的动态代理—JDK的动态代理
    2、基于类的动态代理—cglib
    3、java字节码实现 : javasist

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

动态代理理解:
1、动态代理实现InvocationHandler接口
2、利用Proxy里面的静态方法 Proxy.newProxyInstance()得到代理实例
3、实现InvocationHandler接口中的方法,method.invoke(),执行代理接口中的方法

//自定义动态代理
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 {
        //method指代理接口的方法
        Object result = method.invoke(target, args);//执行调用代理接口的方法
        payServicefee();//执行拓展的公共事务
        return result;
    }
    //拓展的公共事务
    public void payServicefee() {
        System.out.println("交物业费");
    }
}
public class Client {
    public static void main(String[] args) {
        //获取动态代理工具
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //target属性注入要代理的对象
        pih.setTarget(new Host());
        //获取代理对象
        Rent proxy = (Rent) pih.getProxy();
        //代理对象执行方法
        proxy.rent();
    }
}

AOP

方式一:spring的API接口

@Component
public class Log implements MethodBeforeAdvice {
    //   method:要执行的目标对象的方法
    //args:参数
    //target:目标对象
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
    }
}
@Component
public class AfterLog implements AfterReturningAdvice {
    //oreturnValue:返回值
    public void afterReturning(Object turnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"返回结果为:"+turnValue);
    }
}
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.kuang"/>
    <context:annotation-config/>
<!--配置AOP:需要导入aop约束-->
    <aop:config>
        <!--切入点;expression-->
        <aop:pointcut id="myPointCut" expression="execution(* com.kuang.service.*.*(..))"/>
        <!--执行环绕-->
        <aop:advisor advice-ref="log" pointcut-ref="myPointCut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="myPointCut"/>
    </aop:config>
</beans>

方式二:自定义类实现aop(切面定义)

@Component
public class MyAspect {
    public void before(){
        System.out.println("方法执行前");
    }
    public void after() {
        System.out.println("方法执行后");
    }
}
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.kuang"/>
    <context:annotation-config/>

    <aop:config>
        <aop:aspect ref="myAspect">
            <aop:pointcut id="diy" expression="execution(* com.kuang.service.*.*(..))"/>
            <aop:before method="before" pointcut-ref="diy"/>
            <aop:after method="after" pointcut-ref="diy"/>
        </aop:aspect>
    </aop:config>
</beans>

方式三:注解实现aop

@Component
@Aspect
public class AnnotationPointCut {
    @Before("execution(* com.kuang.service.*.*(..))")
    public void before(){
        System.out.println("方法执行前");
    }
    @After("execution(* com.kuang.service.*.*(..))")
    public void after(){
        System.out.println("方法执行后");
    }
}
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.kuang"/>
    <context:annotation-config/>
    <!--开启aop注解-->
    <aop:aspectj-autoproxy/>

</beans>

整合Mybatis

导spring-jdbc包

 		<dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>5.2.9.RELEASE</version>
       </dependency>

spring整合mybatis,就是将数据源、sqlSessionFactory、sqlSession交由IOC容器管理,再由mapper接口的实现类装配sqlsession

<?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">
   <!--将数据源交给IOC-->
   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://192.168.168.132:3306/test"/>
       <property name="username" value="root"/>
       <property name="password" value="root"/>
   </bean>
   <!--将sqlSessionFactory交给IOC,并将数据源装配给sqlSessionFactory-->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource"/>
       <!--可以引入mybatis-config原始的配置文件,其他的配置属性可以生效-->
       <property name="configLocation" value="classpath:mybatis-config.xml"/>
       <!--设置mapper的引入路径,也可以在mybatis-config.xml中配置,然后由configLocation引入-->
       <property name="mapperLocations" value="classpath:mapper/*.xml"/>
   </bean>
   <!--将sqlsession交给IOC容器,Spring框架中由sqlSessionTemplate代替sqlSession-->
   <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
       <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
   </bean>
   <!--mapper接口的实现类,并用set方法,将sqlSessionTemplate装配到实现类中-->
   <bean id="userMapper" class="mapper.UserMapperImpl">
       <property name="sqlSession" ref="sqlSession"/>
   </bean>
</beans>
public class UserMapperImpl  implements  UserMapper {
    private SqlSessionTemplate sqlSession;
    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }
    public List<User> query() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.query();
    }
}
public class MybatisTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        UserMapper mapper = context.getBean("userMapper", UserMapper.class);
        for (User user : mapper.query()) {
            System.out.println(user);
        }
    }
}

声明式事务

  • 要么都成功,要么都失败
  • 事务在开发中十分重要,涉及到数据的一致性,不能马虎!
  • 确保完整性和一致性

事务的ACID原则

  • 原子性 :是指事务的所有操作在数据库中要么全部正确反映出来,要么全部不反映
  • 一致性:必须是使数据库从一个一致性状态变到另一个一致性状态
  • 隔离性:一个事务内部的操作及使用的数据对并发的其他事务是隔离的
  • 持久性:事务一旦提交,对数据库的修改就是永远的

sring中事务管理:

  • 声明式事务
  • 编程式事务
 <!--结合AOP实现事务的织入-->
    <!--配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--给哪些方法配置事务-->
            <!--配置事务的传播性:new propagation-->
            <tx:method name="*" propagation="REQUIRED"/>
            <tx:method name="query" read-only="false"/>
        </tx:attributes>
    </tx:advice>
    <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="myPoint" expression="execution(* mapper.UserMapperImpl.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint"/>
    </aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值