spring基础

一,概述 

1.什么是spring?

Spring框架是轻量级的JavaEE框架,是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层,可以和其他的框架无缝整合。

Spring有两个核心部分:IOCAop

(1)IOC:控制反转,把创建对象的过程交给Spring进行管理

(2)Aop:面向切面,不修改源代码进行功能增强

2.Spring特点

轻量:spring是一个轻量级开发框架基于spring开发的对象不依赖于spring的API,开销小

控制反转(依赖注入):spring运用IOC,使对象依赖的其他对象会通过被动的方式传递,而不是对象自己创建

面相切片:即Aop,将业务逻辑和服务分隔开

容器:Spring 是一个容器, 因为它包含并且管理应用对象的生命周期

框架:Spring是一个从实际开发中抽取出来的框架, 因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率

二,基础应用

1.前期配置

①创建一个普通的java项目工程

②在lib下导入相应的jar包,其中几个包是用于测试方法

③创建applicationContext.xml配置spring约束文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       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
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd "
       default-autowire="byName">
       </beans>

 2.IOC应用

IOC(控制反转):将创建对象的控制权由原本的程序员编写程序创建交给了springIOC容器来创建可以理解为一个容器(帮我们创建bean,管理bean)

bean标签基本属性详解:bean标签把 对象放入到spring容器中
id 属性则是在Spring容器中唯一标识符,可随意写,但建议命名为类相关的名字。
class 属性:确定该类的位置。意思是告诉Spring容器,帮我实例对象的类所在位置。
property标签:设置该类的属性的是
name 则是告诉spring容器 你要设置的该类里面的那一个属性, 后面一般 value,或者ref
value属性 是给属性一般赋值
ref则是给属性 赋引用型的值一般是另一个类的实例化对象
使用构造方法进行注入
constructor-arg 标签:
name 构造方法形参名
value:赋值
ref:赋引用对象名

1.创建对象

以前创建对象方式: new 反射 克隆 反序列化,需要我们手动new

    public static void main(String[] args) {
  
        User user=new User();
    }

IOC创建对象

  <bean id="u1" class="com.hqyj.gyq.entity.User">
        <!--必须有无参构造-->
        <!--<property>写在<bean>代表配置该bean的某个属性,name:属性名称   value:属性的值-->
        <!--user类中属性的setter方法必须有-->
        <property name="userId" value="2"></property>
        <property name="userName" value="zs"></property>
       
</bean>
<!-- 或者-->
  <bean id="u1" class="com.hqyj.gyq.entity.User" autowire="byType">
        <!--通过带参构造初始化属性值-->
        <constructor-arg name="userId" value="1"></constructor-arg>
        <constructor-arg name="userName" value="ls"></constructor-arg>
       
     </bean>

  (1)获取ioc容器对象
      ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  (2)从容器中取出对应的bean
   // 从ioc容器中取出对应的bean--->通过id获取(如果有多个bean。id值不能重复)
       User user = (User) ac.getBean("u1");
   // 从ioc容器中取出对应的bean--->通过类型获取(如果有多个相同类型的bean,会报错)
       User user = (User) ac.getBean(User.class);

2.依赖注入

DI (Dependency Injection):依赖注入是指在 Spring IOC 容器创建对象的过程中,将所依赖的对象通过配置进行注入。我们可以通过依赖注入的方式来降低对象间的耦合度。本质上还是IOC的意思,依赖注入只是IOC的一种具体体现

   <bean id="u1" class="com.hqyj.gyq.entity.User">
         <!--通过带参构造初始化属性值-->
         <constructor-arg name="userId" value="1"></constructor-arg>
         <constructor-arg name="userName" value="ls"></constructor-arg>
         <!--如果属性类型是自定义的bean类型,通过ref引用注入,ref的值:要注入的bean的id值-->
         <property name="idCard" ref="card1"></property>
    </bean>

    <bean id="card1" class="com.hqyj.gyq.entity.IdCard">
          <property name="cId" value="2"></property>
          <property name="address" value="成都"></property>
           <property name="cNum" value="53324534534546576"></property>
     </bean>

其余注入方式(了解):list、map、set、array

3.自动装配

自动装配就是指 Spring 容器在不使用 <constructor-arg> 和<property> 标签的情况下,可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。

①基于xml文件有5中方式
no:默认值,表示不使用自动装配,Bean 依赖必须通过 ref 元素定义。
byName:根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的    Property 的 name 相同,则自动装配这个 Bean 到 Property 中。(表示按属性名称自动装配,XML 文件中 Bean 的 id 必须与类中的属性名称相同)

byType:根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配(XML 文件中 Bean 的 id 与类中的属性名称可以不同,但必须只有一个类型的 Bean。)

constructor:类似于 byType,根据构造方法参数的数据类型,进行 byType 模式的自动装配。(类中构造函数的参数必须在配置文件中有相同的类型)

autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。


自动装配的其他属性:

 scope:控制spring中bean是单例还是多例, prototype:多例 ,singleton:单例

xml配置文件

    <bean id="u" class="com.hqyj.gyq.entity.User" autowire="byType" scope="singleton">
        <property name="userId" value="2"></property>
        <property name="userName" value="zs"></property>
<!--        <property name="idCard" ref="card"></property>-->
    </bean>

    <!--
        IdCard
        id="idCard" 与User类中的属性名要一致(private IdCard idCard;)
        适用于用过名字自动装配
    -->
    <bean id="idCard" class="com.hqyj.gyq.entity.IdCard">
        <property name="cId" value="1"></property>
        <property name="address" value="成都"></property>
        <property name="cNum" value="5124534534534665"></property>
    </bean>

②使用注解

@Component:用来描述Spring中的Bean,仅仅表示一个组件(Bean),并且可以作用在任何层次,使用时只需要将该注解标注在相应类上即可。

@Controller:通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Service:通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Repository:用于将数据访问层(DAO层)的类标识为Spring中的Bean,其功能和@Component相同

@Service:放在service实现类上,作用就等同于在IOC容器中配置了一个bean

@Autowired:可以应用到 Bean 的属性变量、属性的 setter 方法、非 setter 方法及构造函数等,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功,如果ioc容器中没有任何bean类型和要注入的变量类型匹配则报错
@Resource:作用于@Autowired相同,区别在于@Resource可以通过Bean实例名称进行装配,也就是@Resource中的两个重要属性name和type。

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

    <!--开启包扫描-->
    <context:component-scan base-package="com.hqyj.gyq.*"></context:component-scan>
</beans>

service层

package com.hqyj.gyq.service.impl;

import com.hqyj.gyq.dao.UserDao;
import com.hqyj.gyq.entity.User;
import com.hqyj.gyq.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public User queryUserById(Integer id) {
        return userDao.selectUserById(10);
    }
}

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext2.xml" })
public class SpringTest2 {
    @Autowired
    /**
     * @Autowired:自动注入
     */
    private UserService userService;

    @Test
    public void testSpring01(){
        User user = userService.queryUserById(10);
        System.out.println(user);
    }
}

3.AOP

    AOP:AOP(Aspect Oriented Programming)是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解剖对象的内部,
    将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。

    AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。
    横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理、增强处理。

AOP术语:
①通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。

②连接点(Join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的                                    调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。

③切点(PointCut): 可以插入增强处理的连接点。

④ 切面(Aspect): 切面是通知和切点的结合。

⑤ 引入(Introduction):允许我们向现有的类添加新的方法或者属性。

⑥织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的代理对象。

         其中PointCut是用来修饰Join point(定位我们的目标方法); Aspect(切面)包含了Advice(我们要出入或者新增的代码方法)

实现原理:代理模式第一种方式(xml)


1、编写接口UserService,再编写对应的实现类UserServiceImpl:

  public class UserServiceImpl implements UserService {
            @Override
            public void deleteUserById(Integer id) {

                System.out.println("删除成功");
                int num = 1/0;
            }
        }

2、编写切面类TxManager:  

package com.hqyj.cq.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public class TxManager {
    public void start(){
        System.out.println("开启事务!");
    }
    public void commit(){
        System.out.println("提交事务!");
    }
    public void rollback(){
        System.out.println("回滚事务!");
    }
    public void close(){
        System.out.println("关闭事务!");
    }

    public void txManager(ProceedingJoinPoint joinPoint) throws Throwable {
//       执行目标方法
//        joinPoint.proceed();
//        获取目标类
//        Object target = joinPoint.getTarget();
//        获取目标类中执行的方法的参数
//        Object[] args = joinPoint.getArgs();
//        获取执行的目标方法
//        Signature signature = joinPoint.getSignature();
//        System.out.println(signature);

        //        开启事务
        start();
        try{
            //        执行业务代码(目标方法被包裹的位置)
            joinPoint.proceed();
            //        提交事务
            commit();
        }catch (Exception e){
            //            回滚事务
            rollback();
        }finally {
            //            关闭
            close();
        }

    }
}

3、在applicationContext.xml中配置:     

   <!--使用aop编程实现事务的管理-->
            <!--配置目标类-->
            <bean id="userService" class="com.hqyj.cq.service.impl.UserServiceImpl"></bean>
            <!-- 配置切面类(增强类)   -->
            <bean id="tx" class="com.hqyj.cq.aspect.TxManager"></bean>
            <!--aop配置-->
            <aop:config>
                <!--切入点的配置-->
                <!--
                    id:任意取(一般都叫pointcut)
                    expression:
                        第一个*:代表的是方法的返回值
                        com.hqyj.cq.service.impl:包路径
                        第二个*:包下面的所有的类
                        第三个*:类下面的所有的方法
                        (..):方法的参数列表
                -->
                <aop:pointcut id="pointcut" expression="execution(* com.hqyj.cq.service.impl.*.*(..))"/>

                <!--切面类注入-->
                <aop:aspect id="aspect" ref="tx">
                    <!--配置前置通知-->
        <!--            <aop:before method="start" pointcut-ref="pointcut"></aop:before>-->
                    <!--配置后置通知(在没有发生异常的时候执行)-->
        <!--            <aop:after-returning method="commit" pointcut-ref="pointcut"></aop:after-returning>-->
                    <!--配置异常通知-->
        <!--            <aop:after-throwing method="rollback" pointcut-ref="pointcut"></aop:after-throwing>-->
                    <!--配置最后通知(无论是否发生异常,最后都会执行)-->
        <!--            <aop:after method="close" pointcut-ref="pointcut"></aop:after>-->
                    <!--配置环绕通知(自定义业务逻辑)-->
                    <aop:around method="txManager" pointcut-ref="pointcut"></aop:around>
                </aop:aspect>
            </aop:config>

4、编写测试类SpringTest:          

 @RunWith(SpringJUnit4ClassRunner.class)
            @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
            public class SpringTest {
                @Autowired
                private UserService userService;

                @Test
                public void test01(){
                    userService.deleteUserById(2);
                }
            }

第二种方式(注解):

1、编写接口UserService,再编写对应的实现类UserServiceImpl:

     @Service
   public class UserServiceImpl implements UserService {
       @Override
      public void deleteUserById(Integer id) {
                 System.out.println("删除成功");
                            int num = 1/0;
                        }
                    }

 2、编写切面类TxManagerAnno:
             

       @Aspect//声明切面类
                    @Component//交给spring容器管理
                    public class TxManagerAnno {

                    //随意写一个没有返回值的方法用来定义切入点,方法名可以任意,
                    (方法名相当于xml配置中的<aop:pointcut id="pointcut" expression="execution(* com.hqyj.cq.service.impl.*.*(..))"/>
                    的id值)
                        @Pointcut("execution(* com.hqyj.cq.service.impl.*.*(..))")
                        public void pointcut(){

                        }
                    //
                    //    @Before("pointcut()")
                        public void start(){

                            System.out.println("开启事务!");
                        }
                    //
                    //    @AfterReturning("pointcut()")
                        public void commit(){
                            System.out.println("提交事务!");
                        }
                    //    @AfterThrowing("pointcut()")
                        public void rollback(){
                            System.out.println("回滚事务!");
                        }
                    //    @After("pointcut()")
                        public void close(){
                            System.out.println("关闭事务!");
                        }

                        @Around("pointcut()")
                        public void txManager(ProceedingJoinPoint joinPoint) throws Throwable {
                            //        开启事务
                            start();
                            try{
                                //        执行业务代码(目标方法被包裹的位置)
                                joinPoint.proceed();
                                //        提交事务
                                commit();
                            }catch (Exception e){
                                //            回滚事务
                                rollback();
                            }finally {
                                //            关闭
                                close();
                            }

                        }
                    }

3、在applicationContext1.xml中配置:
 

     <!--开启包扫描-->
<context:component-scan base-package="com.hqyj.cq.*"></context:component-scan>
      <!--开启aop注解驱动-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

4、编写测试类SpringTestAnno:
 

       @RunWith(SpringJUnit4ClassRunner.class)
                @ContextConfiguration(locations = {"classpath:applicationContext1.xml"})
                public class SpringTestAnno {
                    @Autowired
                    private UserService userService;

                    @Test
                    public void test01(){
                        userService.deleteUserById(2);
                    }

                    @Test
                    public void test02(){
                        userService.updateUserById(2);
                    }
                }
       @RunWith(SpringJUnit4ClassRunner.class)
                @ContextConfiguration(locations = {"classpath:applicationContext1.xml"})
                public class SpringTestAnno {
                    @Autowired
                    private UserService userService;

                    @Test
                    public void test01(){
                        userService.deleteUserById(2);
                    }

                    @Test
                    public void test02(){
                        userService.updateUserById(2);
                    }
                }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqq00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值