Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack Overflow上关于Spring的一些问答 #18

Open
bitfishxyz opened this issue Aug 15, 2019 · 7 comments
Open

Stack Overflow上关于Spring的一些问答 #18

bitfishxyz opened this issue Aug 15, 2019 · 7 comments
Labels

Comments

@bitfishxyz
Copy link
Member

No description provided.

@bitfishxyz
Copy link
Member Author

<context:annotation-config> and <context:component-scan>之间有什么区别?

https://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan)


<context:annotation-config>表明,对于已经注册到容器中的bean,Spring将会监测这些bean上的注解,并作出处理

假如有这样的类,动物园的一只大熊猫

package zoo.animal;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class Panda {
    private String name;
    private Float weight;
}

然后有一个熊猫守望者:

@Getter @Setter
@NoArgsConstructor
public class PandaWatcherAnnotation {
    private String name;

    @Autowired
    private Panda panda;
}

在熊猫守望者身上有@autowire这个注解。

然后我们写出这样的配置文件

    <!--<context:annotation-config/>-->

    <bean name="panda" class="zoo.animal.Panda" p:name="panda"/>

    <bean name="pandaWatcher" class="zoo.annotation.PandaWatcherAnnotation">
        <property name="name" value="watcher"/>
    </bean>

那么大家觉得我通过容器创建pandaWatcher后,它的属性有没有被注入panda?

答案是否定的,我们需要在配置文件中开启注解模式后,Spring才会处理这个注解。写成这样就行了

    <context:annotation-config/>

    <bean name="panda" class="zoo.animal.Panda" p:name="panda"/>

    <bean name="pandaWatcher" class="zoo.annotation.PandaWatcherAnnotation">
        <property name="name" value="watcher"/>
    </bean>

<context:component-scan>这个配置是开启注解扫描。有了它之后你就不用再配置文件中配置bean了,可以直接在Java代码中给相关的类标注为@Component @Repository。。。

然后呢,你开启<context:component-scan>之后,<context:annotation-config>默认也是会被开启的。

@bitfishxyz
Copy link
Member Author

bitfishxyz commented Aug 15, 2019

@Inject@Autowired之间有什么区别?

https://stackoverflow.com/questions/7142622/what-is-the-difference-between-inject-and-autowired-in-spring-framework-which


@Injectjavax.inject.Inject)是JSR-299提出的标准,用来规范依赖注入的语法。

@Autowired是Spring自带的用于依赖注入的注解。

Spring设计者选择让@Autowired兼容@Inject,二者可以基本互换。唯一的区别是@Autowired@Inject多了一个required属性。

如果你想使用@Inject,需要引入下面的依赖

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

那么,这两个注解我用谁呢?就想豆腐脑是甜的还是咸的,SO网友有激烈的讨论。

支持@Inject

  • @Inject是框架无关的,使用它的话可以在以后切换框架的时候更加方便
  • 虽然我们并不是经常切换DI 框架,但是如果你要写一个可复用的包,使用@Inject可以避免你被Spring绑定死

支持@Autowired

  • 既然你选择了Spring框架,为什么不使用Spring自带的呢?

@bitfishxyz
Copy link
Member Author

为什么通过@Autowired注解的字段的值是null?

https://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null

接上面的例子,我通过这样的方式创建熊猫守望者,为什么发现结果是null?

        PandaWatcherAnnotation pandaWatcher = new PandaWatcherAnnotation();
        System.out.println(pandaWatcher.getPanda());

因为@Autowired之类的注解必须由IOC容器来管理才会生效,你要是通过new的方式创建,这其实是跳过了依赖注入的阶段,所以结果是null。

@bitfishxyz
Copy link
Member Author

在Spring中,Bean到底是什么含义?

https://stackoverflow.com/questions/17193365/what-in-the-world-are-spring-beans

我已经非常熟练的使用Spring了,但我还是搞不清楚Bean究竟意味着什么,谁能解释一下?


你的应用程序中,被Sping Ioc容器管理的对象都称之为Bean。每个Bean的实例化、组装。。。都是由Spring来管理的。

@bitfishxyz
Copy link
Member Author

什么时候使用Bean Factory,什么时候使用Application Context

https://stackoverflow.com/questions/243385/beanfactory-vs-applicationcontext

我知道ApplicationContext 继承自 BeanFactory,但是到底如何选择呢?


Sping的官方文档以及有了解释了: 3.8.1. BeanFactory or ApplicationContext?. 我来总结下

Bean Factory

  • Bean 的实例化与装配

Application Context

  • Bean 的实例化与装配
  • 自动激活 BeanPostProcessor
  • 自动激活 BeanFactoryPostProcessor
  • 方便的获取 MessageSource
  • ApplicationEvent publication

So if you need any of the points presented on the Application Context side, you should use ApplicationContext.

@bitfishxyz
Copy link
Member Author

如何在bean中获得容器本身的引用?

https://stackoverflow.com/questions/129207/getting-spring-application-context


很简单,直接自动装配就行了

@Getter @Setter
@NoArgsConstructor
public class Sheep {
    private String name;

    @Autowired
    private ApplicationContext context;
}

给bean一个ApplicationContext类型的属性,然后自动装配就行了。

public class SheepAnnotationTest {
    private static ApplicationContext context;
    @BeforeClass
    public static void getContext(){
        context = new ClassPathXmlApplicationContext("ioc/annotation/spring.xml");
    }

    @Test
    public void autowire(){
        Sheep sheep = context.getBean("sheep", Sheep.class);
      
        System.out.println(sheep.getContext() == context);
        // true
    }
}

或者可以让我们的bean实现ApplicationContextAware这个接口

@Getter @Setter
@NoArgsConstructor
public class Fish implements ApplicationContextAware {
    private String name;

    private ApplicationContext context;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}

这样容器在初始化的时候就会调用这个方法,并且把ApplicationContext作为参数传递进去

        Fish fish = context.getBean("fish", Fish.class);
        System.out.println(fish.getContext() == context);
        // true

@bitfishxyz
Copy link
Member Author

如何在context:component-scan中,同时扫描多个包?

https://stackoverflow.com/questions/5269450/multiple-packages-in-contextcomponent-scan-spring-config


类似于下面这样

<context:component-scan base-package="x.y.z.service, x.y.z.controller" /> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant