草庐IT

Spring(二)-生命周期 + 自动装配(xml) +自动装配(注解)

xiaoqigui 2023-04-16 原文

1、生命周期

Spring容器的 bean的生命周期;

1.1 默认生命周期

1.1.1 生命周期

  1. 调用构造方法,创建实例对象;
  2. set方法,给实例对象赋值;
  3. init 初始化方法 初始化对象;(手写并配置到bean上init-method="")
  4. 使用容器中的bean对象;
  5. destroy 销毁方法 销毁对象 (手写并配置到bean上destroy-method="")

1.1.2 bean 实体类

Truck

@Data
@ToString
public class Truck {

    //品牌
    private String brand;
	//厂商
    private String factory;
	//价格
    private Double price;

    public Truck() {
        //空参构造方法,观察bean什么时候实例化
        System.out.println("------ 1.调用构造方法,创建实例对象 ------\n");
    }

    public void setBrand(String brand) {
        //任意一个set方法,观察bean什么时候注入参数
        System.out.println("------ 2.set方法,给实例对象赋值 ------");
        this.brand = brand;
    }


    public  void  initTruck(){
        //init初始化方法,观察bean什么时候初始化
        //需要再配置bean的时候,配置init初始化方法
        System.out.println("------ 3.Truck init 初始化方法 初始化对象 ------\n");
        this.brand = "大运";
    }

    public  void  destroyTruck(){
        //destory方法,观察bean什么时候销毁
        //需要再配置bean的时候,配置destory销毁方法
        System.out.println("------ 5.Truck destroy 销毁方法 销毁对象 ------\n");
    }
	//这里方法上标注的序号是测试后得来的;
}

1.1.3 bean 配置

spring-lifecycle.xml

<!-- spring容器中bean的生命周期  默认生命周期 -->
<bean id="truck" class="com.kgc.spring.lifecycle.Truck" init-method="initTruck" destroy-method="destroyTruck">
    <property name="brand" value="江淮"></property>
    <property name="factory" value="安徽"></property>
    <property name="price" value="200000"></property>
</bean>

1.1.4 测试

public class TestSpringLifeCycle {

    //定义全局容器对象,如果需要关闭容器对象,
    //必须使用ApplicationContext的子接口 ConfigurableApplicationContext
    //ApplicationContext接口主要各种属性的get方法;
    //ConfigurableApplicationContext重在对各种属性的配置;
    
//    private ApplicationContext context;
    private ConfigurableApplicationContext context;

    @Before
    public void initApplicationContext(){
        context = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
    }

    //测试spring 容器的bean的生命周期,默认和加了处理器两种场景
    @Test
    public void  testSpringBeanLifeCycle(){

        //从容器中,获取Truck的是实例对象
        Truck truck = context.getBean("truck", Truck.class);

        //使用对象
        System.out.println("------ 4.使用容器中的bean对象"+truck +" ------");

        //关闭容器
        context.close();

    }

}

输出结果:

//可以得出 spring中bean的 默认生命周期
------ 1.调用构造方法,创建实例对象 ------

------ 2.set方法,给实例对象赋值 ------
    
------ 3.Truck init 初始化方法 初始化对象 ------
    
------ 4.使用容器中的bean对象Truck(brand=大运, factory=安徽, price=200000.0) ------
    
------ 5.Truck destroy 销毁方法 销毁对象 ------

1.1.5 ApplicationContext 和 ConfigurableApplicationContext

参考博客: ApplicationContext和ConfigurableApplicationContext解析

  • ApplicationContext接口主要 各种属性的get方法;

  • ConfigurableApplicationContext重在对 各种 属性的配置;

1.2 增加后置处理器

1.2.1 生命周期

1.调用构造方法,创建实例对象;

2.set方法,给实例对象赋值;

3-1.后置处理的 before 方法;

3.初始化方法 初始化对象;

3+1.后置处理器的的 after 方法;

4.使用容器中的bean对象;

5.destroy 销毁方法 销毁对象;

1.2.2 后置处理器

  • 要求:必须实现 BeanPostProcessor 接口

  • 自定义 bean 的 后置处理器,对容器中所有的bean统一处理(生效)

  • 要生效的话,必须将此处理器放到容器中(配置到spring的核心配置文件中,增加处理器的实例配置);

注意:当前案例,只对容器中的一个实例处理

MyBeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //在容器中bean的实例对象调用 初始化方法 前 自动调用(init方法可以没有,不影响)
        //模拟处理容器中的bean,接下来的写法,仅限于当前的用法案例(容器中就 只有一个 卡车实例)
        Truck truck = (Truck)bean;

        System.out.println("++++++ 容器中的卡车对象 "+truck+"++++++");

        System.out.println("++++++ 3-1,后置处理的 before 方法 ++++++");
        truck.setBrand("后置处理的before方法");
        System.out.println("++++++ 处理后的 卡车对象 "+truck+" ++++++\n");

        return truck;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //bean 初始化方法 执行 后,调用此方法处理bean
        Truck truck = (Truck)bean;

        System.out.println("++++++ 初始化容器中的卡车对象 "+truck+"++++++");

        System.out.println("++++++ 3+1,后置处理器的的 after 方法 ++++++");
        truck.setBrand("after");
        System.out.println("++++++ 初始化后 处理后的 卡车对象 "+truck+" ++++++\n");
        return truck;

    }
}

1.2.3 bean 配置

在配置文件中配置 MyBeanPostProcessor;

<!-- 配置后置处理器的实例,自动放入容器中,可以自动生效 (容器中所有的实例生效) -->
<bean class="com.kgc.spring.lifecycle.MyBeanPostProcessor"></bean>

1.2.4 测试

跟默认生命周期的测试代码一致;

输出结果:

------ 1.调用构造方法,创建实例对象 ------

------ 2.set方法,给实例对象赋值 ------
++++++ 容器中的卡车对象 Truck(brand=江淮, factory=安徽, price=200000.0)++++++
    
++++++ 3-1,后置处理的 before 方法 ++++++ ------ 2.set方法,给实例对象赋值 ------
++++++ 处理后的 卡车对象 Truck(brand=后置处理的before方法, factory=安徽, price=200000.0) ++++++

------ 3.Truck init 初始化方法 初始化对象 ------
++++++ 初始化容器中的卡车对象 Truck(brand=大运, factory=安徽, price=200000.0)++++++
    
++++++ 3+1,后置处理器的的 after 方法 ++++++ ------ 2.set方法,给实例对象赋值 ------
++++++ 初始化后 处理后的 卡车对象 Truck(brand=after, factory=安徽, price=200000.0) ++++++

------ 4.使用容器中的bean对象Truck(brand=after, factory=安徽, 
                           
------ 5.Truck destroy 销毁方法 销毁对象 ------

1.2.3 BeanPostProcesso

参考博客:BeanPostProcessor简介

BeanPostProcessor官方定义为工厂钩子,我们也俗称后置处理器。它允许自定义修改新的bean实例,例如检查标记接口或用代理包装它们。应用程序上下文可以在其bean定义中自动检测BeanPostProcessor bean,并将它们应用于随后创建的任何bean。

BeanPostProcessor 的 前置处理后置处理

![image-20220826150821502](Spring-02 生命周期 + 自动装配(xml) +自动装配(注解).assets/image-20220826150821502.png)

2、自动装配(xml)

2.1 bean 实体类

Person

@Data
public class Person {
    //昵称
    private String nickName;
    //车子
    private Car car;
    //房子
    private House house;
}

Car

@Data
public class Car {
    //品牌
    private String brand;
	//厂商
    private String factory;
	//价格
    private Double price;
}

House

@Data
public class House {
    //户型
    private  String type;
    //面积
    private double area;
    //价格
    private  Integer price;
}

2.2 bean 配置 (byType)

autowire="byType":根据属性 的 类型自动装配;

spring-auto.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">

    <!-- spring的自动装配方式,基于xml配置文件方式,掌握 -->
    <!-- 容器中实例化一个容器的Car对象 -->
    <bean id="car" class="com.kgc.spring.auto.Car">
        <property name="brand" value="Bnw520"></property>
        <property name="factory" value="华晨"></property>
        <property name="price" value="450000"></property>
    </bean>

    <!-- 容器中实例化一个容器的House对象 -->
    <bean id="house" class="com.kgc.spring.auto.House">
        <property name="type" value="三室一厅"></property>
        <property name="area" value="96"></property>
        <property name="price" value="2800000"></property>
    </bean>

    <!-- 根据类型自动装配 -->
    <bean id="person" class="com.kgc.spring.auto.Person" autowire="byType">
        <property name="nickName" value="huayu"></property>
    </bean>

</beans>

2.3 测试

public class TestSpringAutoUserXml {
    private ApplicationContext context;

    @Before
    public void initApplicationContext(){
        context = new ClassPathXmlApplicationContext("spring-auto.xml");
    }

    @Test
    public  void testSpringAuto(){
        Person person = context.getBean("person", Person.class);
        
        //使用对象
        System.out.println("容器中的person对象:"+person);

    }

}

输出结果:

容器中的person对象:Person(
    					nickName=huayu, 
                        car=Car(brand=Bnw520, factory=华晨, price=450000.0), 
                        house=House(type=三室一厅, area=96.0, price=2800000)
						)

2.4 bean 配置 (多个同类型bean)

bean 配置:

其他不变,多增加一个Car类型的实例bean;

<bean id="car" class="com.kgc.spring.auto.Car">
    <property name="brand" value="Bnw520"></property>
    <property name="factory" value="华晨"></property>
    <property name="price" value="450000"></property>
</bean>

<bean id="carNew" class="com.kgc.spring.auto.Car">
    <property name="brand" value="AudiA6"></property>
    <property name="factory" value="一汽"></property>
    <property name="price" value="450000"></property>
</bean>

测试,报错信息:

No qualifying bean of type 'com.kgc.spring.auto.Car' available: expected single matching bean but found 2: car,carNew

总结:autowire="byType" 当有多个相同类型的bean时无法确定要装配的 bean;

2.5 bean 配置(byName)

其他配置信息不变,设置 autowire="byName" ,根据 属性 的 名字 自动装配;

<bean id="person" class="com.kgc.spring.auto.Person" autowire="byName">
    <property name="nickName" value="hauyu"></property>
</bean>

测试输出结果:

容器中的person对象:Person(
    					nickName=huayu, 
                        car=Car(brand=Bnw520, factory=华晨, price=450000.0), 
                        house=House(type=三室一厅, area=96.0, price=2800000)
						)

总结

  • byType:根据类型自动装配:
    • 根据实体属性的  类型,到容器中,根据  bean类型  进行唯一匹配,如果可以匹配到对应类型的bean的实例,就会执行自动装配, 如果不能唯一匹配(同类型的bean有多个),会报错;
  • byName: 根据名称自动装配:
    • 根据属性属性名,到容器中,根据 bean的id 属性值,进行唯一匹配,如果能够成功匹配,执行自动装配, 如果匹配不到,不执行自动装配,实体属性为null;

3、自动装配 (注解)

3.1 注解

  • @Component 普通组件注解;
  • @Repository 持久层注解
  • @Service 业务层注解
  • @Controller 控制层注解

3.3.1 注解的原理

默认情况下:spring自动将分层组件(@Controller,@Service,@Repository,@component)标识的类(不是接口),自动创建实例对象放入容器中,使用bean的标识id值为 对应类名首字母小写 就相当于,帮我们手动添加了配置 :

<bean id="分层注解标识类的类名首字母小写" class="分层注解标识类的全类名"> ... <bean>

3.1.2 自定义id 属性

如果不想使用默认的类名首字母小写,我们可以使用注解的value属性执行一个自定义的id值;
比如:@Service(value="自定义的id值"),注解只有value属性,可以省略value执行,简化为@Service("自定义的id值")

3.1.3 分层组件的目的

分层组件的目的,就仅仅是为了方便开发人员明确当前注解所在的类所对应的角色,在使用上,建议使用,按照官方定义的使用,防止模糊不清;在springMVC框架中@Controller有特殊含义;

3.2 配置文件

spring创建容器对象时,如果解析到 component-scan 组件扫描配置,会将base-package指定的基包(父包)及其子包所有增加了分层组件的类,自动创建实例,放进容器中;

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       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
">
 <!-- 组件扫描:注解标识的组件,必须通过组件扫描配置,才可以添加到spring的容器中--> 
 <context:component-scan base-package="com.kgc.spring.acnocation" >    </context:component-scan>

</beans>

3.3 默认id属性 测试

3.3.1 实体

@Component
public class User {
    //用户名
    @Value("huayu") //@Value()  自动装配参数
    private  String userName;
    //用户密码
    @Value("123")
    private String userPwd;
}

3.3.2 测试

@Test
public  void testSpringAutoUserAnnotation(){
	
    User user = context.getBean("user", User.class);
   
    System.out.println(user);
    //User(userName=huayu, userPwd=123)

}

3.4 自定义id属性 测试

3.4.1 实体(自定义id属性)

@Component(value = "myUser")
public class User {
    //用户名
    private  String userName;
    //用户密码
    private String userPwd;
}

3.4.2 测试

@Test
public  void testSpringAutoUserAnnotation(){

    //User user = context.getBean("user", User.class);
    //自定义id后,默认id不能使用: No bean named 'user' available
    
    //必须使用自定义id
    User user = context.getBean("myUser", User.class);
    
    System.out.println(user);
    //User(userName=huayu, userPwd=123)

}

3.5 自动装配

3.5.1 @Autowired

  • 组件自动装配,可以实现实体属性类型的自动装配,自动到spring的容器中,根据当前属性的类型或者名称进行注入,如果容器中能匹配到,就直接将实例对象注入到当前实体属性上,无序手动指定;
  • @Autowired自动装配原理:首先会根据byType方式,进行自动装配,
    • 如果不能唯一匹配(存在同类型多个实例对象),会再次尝试使用byName方式,根据当前实体属性名,到容器中进行匹配(容器中bean的id值),如果能唯一匹配,直接执行自动装配,
  • 默认情况下,@Autowired注解标识的实体属性,必须被装配
    • 如果装配失败,就直接抛出异常;
    • 如果不需要校验必须被装配(项目启动,如果装配失败,项目是起不来);
    • 通过指定required = false,去除必须执行自动装配的校验(即便容器中找不到装配的实例,也不会抛出异常);
  • 如果自动装配,容器中存在多个同类型的bean对象,可以使用注解@Qualifier("容器中同类型多个bean的某个id值"),实现指定到容器中,找对应的bean实例对象,进行自动装配;
  • 底层是如何做的:在指定要扫描的包时,<context:component-scan> 元素会自动注册一个bean的后置处理器:AutowiredAnnotationBeanPostProcessor的实例。该后置处理器可以自动装配标记了@Autowired、@Resource或@Inject注解的属性

3.5.2 实体

People

@Data
@Component("myPeople")
public class People {
    //昵称
    @Value("huayu")
    private String name;
    //玩具
    @Autowired
    private Toy toy;

}

Toy接口

public interface Toy {
    //得到玩具
    public void getToy();

}

ToyImpl1

@Component("toy1")
public class ToyImpl1 implements Toy {

    @Value("玩具车")
    private String toyName;

    @Override
    public void getToy() {
        System.out.println(this.toyName);
    }
}

3.5.3 测试

注意:可以通过接口类型获取实现类(推荐使用);

@Test
public  void testAutowired  (){
    People people = context.getBean("myPeople", People.class);

    people.getToy().getToy(); //玩具车

}

3.5.4 存在多个相同类型的bean

当存在多个相同类型的bean不能唯一匹配,会自动装配错误

在写一个Toy实现类,ToyImpl2

@Component("toy2")
public class ToyImpl2 implements Toy {

    @Value("尤克里里")
    private String toyName;

    @Override
    public void getToy() {
        System.out.println(this.toyName);
    }

}
3.5.4.1 测试

报错信息(项目无法启动):

No qualifying bean of type 'com.kgc.spring.acnocation.bean.Toy' available: expected single matching bean but found 2: toy1,toy2

主要信息:类型无法唯一匹配;

3.5.4.2 required = false 允许不装配

People

@Data
@Component("myPeople")
public class People {

    //昵称
    @Value("huayu")
    private String name;

    //玩具
    @Autowired (required = false)
    private Toy toy;

}

项目可以启动但是还是报错(一般项目中不会有两个相同类型的实现类;)

3.5.4.3 @Quailfy

People

@Data
@Component("myPeople")
public class People {

    //昵称
    @Value("huayu")
    private String name;

    //玩具
    @Autowired 
    @Qualifier("toy2") //指定bean的id值
    private Toy toy;

}
3.5.4.4 测试
@Test
public  void testAutowired  (){
    People people = context.getBean("myPeople", People.class);

    System.out.println(people.getToy());
    //com.kgc.spring.acnocation.bean.ToyImpl2@15d9bc04
    
    people.getToy().getToy();
    //尤克里里

}

3.6 指定扫描 排除扫描

3.6.1 指定扫描

include-filter

指定扫描(包含扫描):

  • 只会扫描指定的或者某类组件(使用分组扫描),加入到容器中;
  • 但是必须配合父标签的user-default-filter使用,默认值是true,就是全部扫描;
  • 指定扫描,如果要生效必须改为false
  • 指定扫描某类组件,type="annotation" expression="某类组件注解的全类名";
  • 指定扫描某个类,type="assignable" expression="某个类的全类名";
3.6.1.1 指定扫描某类组件

type="annotation"

  • org.springframework.stereotype.Component
  • org.springframework.stereotype.Repository
  • org.springframework.stereotype.Service
  • org.springframework.stereotype.Controller
<!-- 指定扫描 @Component 组件 -->
<context:component-scan base-package="com.kgc.spring.acnocation" use-default-filters="false" >
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>
3.6.1.2 指定扫描某个类

type="assignable"

<!-- 指定扫描 ToyImpl1 -->
<context:component-scan base-package="com.kgc.spring.acnocation" use-default-filters="false" >
    <context:include-filter type="assignable" expression="com.kgc.spring.acnocation.bean.ToyImpl1"/>
</context:component-scan>

3.6.2 排除扫描

exclude-filter

  • 排除扫描(剔除扫描):排除指定的某类组件不加入到容器中,处理排除外的其他组件,仍然会被添加到容器中;
  • 不需要配合父标签,use-default-filters="true" 因为,默认就是在全部扫描的基础上剔除;
  • 排除扫描某类组件,type="annotation" expression="某类组件注解的全类名";
  • 排除扫描某个类,type="assignable" expression="某个类的全类名";
3.6.2.1 排除扫描某类组件

type="annotation"

<!-- use-default-filters="true" 可写可不写 -->
<!-- 排除扫描 @Component组件 -->
<context:component-scan base-package="com.kgc.spring.acnocation" use-default-filters="true" >
	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
</context:component-scan>
3.6.2.2 排除扫描个类

type="assignable"

<!-- 排除扫描 ToyImpl1 -->
<context:component-scan base-package="com.kgc.spring.acnocation" >
	<context:exclude-filter type="assignable" expression="com.kgc.spring.acnocation.bean.ToyImpl1"/>
</context:component-scan>

有关Spring(二)-生命周期 + 自动装配(xml) +自动装配(注解)的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  7. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  8. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  9. ruby-on-rails - Spring 不起作用。 [未初始化常量 Spring::SID::DL] - 2

    我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li

  10. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

随机推荐