0
点赞
收藏
分享

微信扫一扫

Spring泛览一

一叶轻舟okok 2021-09-27 阅读 24

Spring


  1. spring-core: 核心工具类
  2. spring-bean: 用于访问配置文件,创建和管理bean
  3. spring-context: 提供在基础IOC功能上的扩展服务,例如任务调度,邮件服务等
  4. spring-expression: Spring表达式语言
  5. com.springsource.org.apache.commons.logging.jar: 第三方的主要用于处理日志

IOC

DI

BeanFactory和Applicaton的区别

  • BeanFactory:采用延时加载,第一次getBean时才会初始化Bean
  • Applicaton: 是对BeanFactory的扩展,采用及时加载,并且提供了很多扩展例如事件传递,国际化处理等

Spring容器装载的三种方式

//Spring容器加载的3种方式
//第一种:ClassPathXmlApplicationContext,后面路径是src路径开始(最常用)
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");

//第二种:通过文件系统路径[绝对路径]
//ApplicationContext context=new FileSystemXmlApplicationContext("E:\\WorkSpace\\IDEA\\Demo01\\src\\beans.xml");
//第三种:使用BeanFactory(了解)
// BeanFactory context=new XmlBeanFactory(new FileSystemResource("E:\\WorkSpace\\IDEA\\Demo01\\src\\beans.xml"));
UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
userService.add();

装配bean的三种方式

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

    <!--方式一、new实现类-->
    <bean id="userService" class="com.zengqiang.service.UserServiceImpl">
        <property name="name" value="zengqiang"></property>
    </bean>

    <!--方式二、通过静态工厂方法-->
    <bean id="userService2" class="com.zengqiang.service.UserServiceFactory" factory-method="createInstance">
    </bean>
    <!--方式二、通过实例工厂方法-->
    <bean id="factory" class="com.zengqiang.service.UserServiceFactory">
    </bean>
    <bean id="userService3" factory-bean="factory" factory-method="createInstance2"></bean>

</beans>
public class UserServiceFactory {
    public static IUserService createInstance() {
        return new UserServiceImpl();
    }
    public  IUserService createInstance2() {
        return new UserServiceImpl();
    }
}
  • 测试方式
 @Test
    public void test1() {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");

        //方式一
//        UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
//        userService.add();
        //方式二:但是二三方法要注意,spring如果用3.x版本则jdk需要降低到1.7否则报IllegalArgumentException异常
//        UserServiceImpl userService2= (UserServiceImpl) context.getBean("userService2");
//        userService2.add();

        //方式三
        UserServiceImpl userService3= (UserServiceImpl) context.getBean("userService3");
        userService3.add();
    }

bean的作用域(scope)

  • singleton
  • prototype
  • request(了解)
  • session(了解)
  • globalSession(了解)
<bean id="userService" class="com.zengqiang.service.UserServiceImpl" scope="singleton">
        <property name="name" value="zengqiang"></property>
    </bean>

bean的生命周期(了解)

  • instantiate bean对象实例化
  • populate properties 封装属性
  • 如果Bean实现BeanNameAware 执行 setBeanName
  • 如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
  • 如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
  • 如果Bean实现InitializingBean 执行 afterPropertiesSet
  • 调用< bean init-method="init"> 指定初始化方法 init
  • 如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
    执行业务处理
  • 如果Bean实现 DisposableBean 执行 destroy
  • 调用< bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy

参数注入

通过构造方法注入


public class User {

    private String username;
    private String password;
    private int age;

    public User(String username, int age) {
        this.username = username;
        this.age = age;
    }


    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

<?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="stu" class="com.zengqiang.service.User" >
        <!--相当于调用
        public User(String username, String password) {
        this.username = username;
        this.password = password;
        }构造方法-->
        <constructor-arg name="username" value="zengqiang"></constructor-arg>
        <constructor-arg name="password" value="qiangzeng"></constructor-arg>
    </bean>


    <!--通过索引加类型给构造方法复制-->
    <bean id="stu1" class="com.zengqiang.service.User" >
        <!--相当于调用该构造
        public User(String username, int age) {
        this.username = username;
        this.age = age;
        }
        -->
        <!--index代表参数索引,根据type类型判断该使用那个构造方法-->
        <constructor-arg index="0" value="zengqiang" type="java.lang.String"></constructor-arg>
        <constructor-arg index="1" value="1" type="java.lang.Integer"></constructor-arg>
    </bean>


</beans>

set方法注入

<!--通过set方法往bean注入属性值-->
    <bean id="stu" class="com.zengqiang.service.User" >
        <property name="username" value="zengqiang"></property>
        <property name="password" value="qiang"></property>
        <property name="age" value="1"></property>
    </bean>
public class User {

    private String username;
    private String password;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

其他还有通过p命名空间注入值,不细谈(知道即可)

SpEL表达式(了解)

<?xml version="1.0" encoding="UTF-8"?>
<!--xmlns xml namespace:xml命名空间-->
<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 http://www.springframework.org/schema/beans/spring-beans.xsd">


   <!--
   SpEL:spring表达式
        <property name="" value="#{表达式}">
        #{123}、#{'jack'} : 数字、字符串
        #{T(类).字段|方法}   :静态方法或字段
        #{beanId}   :另一个bean引用
        #{beanId.propName}  :操作数据
        #{beanId.toString()}    :执行方法
   -->
    <!--创建一个地址对象-->
    <bean id="address" class="com.gyf.model.Address">
        <property name="name" value="天河"></property>
    </bean>
    <bean id="customer" class="com.gyf.model.Customer">
        <!--{beanId.propName}   :操作数据,此时address代表上面的bean的id,name,代表Bean的name属性此时相当于getName-->
        <property name="name" value="#{address.name}"></property>

        <property name="name" value="#{'gyf'.toUpperCase()}"></property>
        <!-- Math.PI 调用静态方法-->
        <property name="pi" value="#{T(java.lang.Math).PI}"></property>

        <!--
        一个对象引用另外一个对象两写法
        1.ref: 引用<property name="address" ref="address"></property>
        2.SpEL:<property name="address" value="#{address}"></property>
        -->
        <property name="address" value="#{address}"></property>
    </bean>
</beans>

集合注入


  1. 数组:< array>
  2. List:< list>
  3. Set:< set>
  4. Map:< map> map存放k/v键值对,使用< entry>描述
  5. Properties: < props> < prop key="">< /prop>

<?xml version="1.0" encoding="UTF-8"?>
<!--xmlns xml namespace:xml命名空间-->
<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 http://www.springframework.org/schema/beans/spring-beans.xsd">



    <bean id="programmer" class="com.gyf.model.Programmer">
        <property name="cars">
            <!--1. list数据注入-->
            <list>
                <value>ofo</value>
                <value>mobai</value>
                <value>宝马</value>
            </list>
        </property>

        <!-- set数据注入-->
        <property name="pats">
            <set>
                <value>小黑</value>
                <value>小黄</value>
                <value>小白</value>
            </set>
        </property>


        <!-- map数据注入-->
        <property name="infos">
            <map>
                <entry key="name" value="gyf"></entry>
                <entry key="age" value="108"></entry>
                <entry key="ip" value="127.0.0.1"></entry>
            </map>
        </property>

        <!--Properties 数据注入-->
        <property name="mysqlInfos">
            <props>
                <prop key="url">mysql:jdbc://localhost:3306/dbname</prop>
                <prop key="user">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>

        <!-- 数组注入-->
        <property name="members">
            <array>
                <value>哥哥</value>
                <value>弟弟</value>
                <value>妹妹</value>
                <value>姐姐</value>
            </array>
        </property>
    </bean>
</beans>
public Properties getMysqlInfo() {
        return mysqlInfo;
    }

public void setMysqlInfo(Properties mysqlInfo) {
    this.mysqlInfo = mysqlInfo;
}

private Properties mysqlInfo;

说明:Properties类似于Object,打印出来也是类似于map

@Component注解的使用


  1. @Component取代< bean class="">
  2. @Component("id")取代< bean class="" id="">

基本案例:

@Test
    public void test1() {
        /**
         * 1.默认Spring不开启注解功能
         * 2.需要去.xml中开启注解
         */
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //如果@Component没有配置id,则通过类型获取
        IUserService service= context.getBean(UserServiceImpl.class);
        service.add();
    }

<?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:annotation-config/>
    <!--注解的位置,Spring扫描的位置,地址是随意的层级,此处使用了最大层级-->
    <context:component-scan base-package="com.zengqiang"/>
</beans>

说明:
添加xmlns:context="http://www.springframework.org/schema/context"
然后在xsi:schemaLocation中添加
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
这样配置下面的context才有提示

web开发,提供3个@Component注解衍生注解(功能一样)取代< bean class="">


  1. @Repository(“名称”):dao层

  2. @Service(“名称”):service层

  3. @Controller(“名称”):web层

  4. @Autowired:自动根据类型注入,可以用来消除 set ,get方法

  5. @Qualifier(“名称”):指定自动注入的id名称

  6. @Resource(name=“名称”),相当于4,5的综合

  7. @PostConstruct 自定义初始化,相当于init-method

  8. @PreDestroy 自定义销毁,相当于destory-method

  9. @Scope("prototype")多例,默认单例


基本案例

注解形式

<?xml version="1.0" encoding="UTF-8"?>
<!--xmlns xml namespace:xml命名空间-->
<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"
       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">

    <!-- 1.配置dao-->
    <bean id="userDao" class="com.gyf.dao.UserDaoImpl"></bean>

    <!-- 2.配置service -->
    <bean id="userService" class="com.gyf.service.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

    <!--3.配置action-->
    <bean id="userAction" class="com.gyf.web.action.UserAction">
        <property name="userService" ref="userService"></property>
    </bean>
</beans>

注解形式

@Controller
@Scope("prototype")//多例,默认单例
public class UserAction{

    /**
     * Autowired是根据类型注入值
     * 如果你是一个接口,从容器找接口实现类
     * 如果你就是一个类,就查找类
     */
    @Autowired//spring自动注入userService赋值【用的多】
    //@Qualifier("myUserService")//根据指定的id注入属性【用的比较少】

    //@Resource(name = "myUserService")//等效于前面两行代码【用的比较少】
    private IUserService userService;

    public void save(User user){
        System.out.println("action save方法 ");
        userService.add(user);
    }
}

spring(数据库)事务隔离级别分为四种(级别递减):

  • 1、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;

  • 2、REPEATABLE READ(重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

  • 3、READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

  • 4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。

脏读、不可重复读、幻读:

  • 脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。

也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。

  • 不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。

也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。

  • 幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

也就是说,当前事务读第一次取到的数据比后来读取到数据条目少。

不可重复读和幻读比较:

举报

相关推荐

0 条评论