• spring入门学习感悟


    1:ioc:控制反转

    控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是有外部容器负责创建和维护的(获取依赖对象的过程被反转了)

    2:di:依赖注入,它是一种控制反转的一种实现方法,ioc容器运行期间,将某种对象的依赖关系动态的注入进去。
    3:这样的好处是编程代码耦合度低,二是所有对象都有容器管理

    4 :新加入的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" >

    <bean id="oneInterface" class="com.imooc.ioc.interfaces.OneInterfaceImpl"></bean>

    </beans>

    5:测试基类

    public class UnitTestBase {

    private ClassPathXmlApplicationContext context;

    private String springXmlpath;

    public UnitTestBase() {}

    public UnitTestBase(String springXmlpath) {
    this.springXmlpath = springXmlpath;
    }

    @Before
    public void before() {
    if (StringUtils.isEmpty(springXmlpath)) {
    springXmlpath = "classpath*:spring-*.xml";
    }
    try {
    context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\s]+"));
    context.start();
    } catch (BeansException e) {
    e.printStackTrace();
    }
    }

    @After
    public void after() {
    context.destroy();
    }

    @SuppressWarnings("unchecked")
    protected <T extends Object> T getBean(String beanId) {
    try {
    return (T)context.getBean(beanId);
    } catch (BeansException e) {
    e.printStackTrace();
    return null;
    }
    }

    protected <T extends Object> T getBean(Class<T> clazz) {
    try {
    return context.getBean(clazz);
    } catch (BeansException e) {
    e.printStackTrace();
    return null;
    }
    }

    }
    6: 测试用例
    @RunWith(BlockJUnit4ClassRunner.class)
    public class TestOneInterface extends UnitTestBase {

    public TestOneInterface() {
    super("classpath*:spring-ioc.xml");
    }

    @Test
    public void testSay() {
    OneInterface oneInterface = super.getBean("oneInterface");
    oneInterface.say("This is a test.");
    }

    }

    7:bean 容器初始化三种方式
    FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("E:/applicationContext.xml");
    ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("classPath:applicationContext.xml");
    通常在web.xml中如下配置:
    
    <context-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath*:spring.xml  
            </param-value>  
        </context-param>  
        <listener>  
            <listener-class>org.springframework.web.context.ContextLoaderListener  
            </listener-class>  
        </listener>  
    
    

    :8:spring 注入有两种注入方式

         分别是设值注入和构造函数注入

        xml 配置如下

      构造函数

    构造函数参数名必须为injectionDAO

    <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
    <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
    </bean>
    <bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
          
    设值注入属性名必须为injectionDAO (目的是为了生成的set方法必须为setInjectionDAO)
    <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
    <property name="injectionDAO" ref="injectionDAO"></property>
    </bean>
    <bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>

    9:Spring 3中为Bean定义了5中作用域,分别为singleton(单例)、prototype(原型)、request、session和global session,5种作用域说明如下:

         singleton:单例模式,Spring IoC容器中只会存在一个共享的Bean实例

         prototype:原型模式,每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例

         request:在一次Http请求中,容器会返回该Bean的同一实例。而对不同的Http请求则会产生新的Bean,而且该bean仅在当前Http Request内有效。

         session:在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效

         global Session:在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效

    配置方式如下

       <beans>     

       <bean id="beanScope" class="com.imooc.bean.BeanScope" scope="singleton"></bean>

     </beans>

     10:spring bean生命周期 定义,初始化,使用,销毁

    11:bean初始化和销毁方法的几种实现

    第一种方法,继承InitializingBean和DisposableBean方法
    继承前者实现afterPropertiesSet方法,继承后者实现destroy方法

    第二种方法:

    <bean class="com.test.spring.initorder.InitOrderBean" init-method="init" destroy-method="destory">
      </bean>

    第三种方法:全局配置初始化和销毁方法(不是必须实现的)
    <beans default-init-method="defautInit" default-destroy-method="defaultDestroy">

    第一种比第二种先执行

     12:spring中提供了一些以Aware结尾的接口实现了Aware接口的bean在被初始化之后可以获取相应的资源

    ApplicationContextAware 使用

    public class MoocApplicationContext implements ApplicationContextAware  {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    throws BeansException {
    System.out.println("MoocApplicationContext : " + applicationContext.getBean("moocApplicationContext").hashCode());
    }

    }

     13:BeanNameAware


    public class MoocBeanName implements BeanNameAware, ApplicationContextAware {

    private String beanName;
    //主要是用来获取beanname的值
    @Override
    public void setBeanName(String name) {
    this.beanName = name;
    System.out.println("MoocBeanName : " + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    throws BeansException {
    System.out.println("setApplicationContext : " + applicationContext.getBean(this.beanName).hashCode());
    }

    }

    14: bean自动装配

    <beans default-autowire="byName">
    <bean id="autoWiringService" class="com.imooc.autowiring.AutoWiringService" ></bean>

    <bean id="autoWiringDAO" class="com.imooc.autowiring.AutoWiringDAO" ></bean>
    </beans>

    <beans default-autowire="byType">
    <bean id="autoWiringService" class="com.imooc.autowiring.AutoWiringService" ></bean>

    <bean class="com.imooc.autowiring.AutoWiringDAO" ></bean>
    </beans>
    private AutoWiringDAO autoWiringDAO1;

    public void setAutoWiringDAO1(AutoWiringDAO autoWiringDAO2) {
    System.out.println("setAutoWiringDAO");
    this.autoWiringDAO1 =autoWiringDAO2;
    }

    public void say(String word) {
    this.autoWiringDAO1.say(word);
    }
    
    
    15: annotation-config 和 component-scan的不同

    这个问题也算看了好几遍还没记住的问题,先抛结论,如果是为在Spring中声明注解,不需xml配置的话,使用<context:component-scan base-package="com">类似的就可以实现无bean声明。 
    然后,我们详细说下这两个配置的作用: 
    <context:annotation-config/>的作用:它是对已注册Bean的进行操作的配置,也就是说,Bean需要首先通过某种方式(比如Xml配置,或者其他注解)被注册,然后使用这个配置,可以对已注册的Bean进行进一步操作(比如注入到某个类的内部),也就是说,这个配置是用于“激活”已注册的Bean的,让已注册的Bean开始工作。 
    仅会查找在同一个applicationcontext中的bean注解
    <context:component-scan />的作用:<context:component-scan />首先有和<context:annotation-config/>一样的作用,此外,它还可以扫描指定包下的类,将拥有注解的它们注册到Spring中。 
    综上,也就是说,如果用<context:annotation-config/>,我们还需要配置Xml注册Bean,而使用<context:component-scan />的话,注册的步骤都免了,当然前提是我们对需要扫描的类使用的注解(比如@Componet,@Service),而如果同时使用两个配置的话,<context:annotation-config/>会被忽略掉。


    <!-- 扫描@Controller注解 -->
    <context:component-scan base-package="com.fq.controller">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    16: Spring中用@Component、@Repository、@Service和 @Controller等标注的默认Bean名称会是小写开头的非限定类名 也可以通过如下方式指定name
    1 @Service("TestService")  
    2 public class TestService {
    3   }  

    或者自定义命名规范以及设置代理方式
     <context:component-scan base-package="com.zhyonk.bean" scoped-proxy="interfaces"  name-generator="com.zhyonk.framwork.simpleNameGenerator">
            
        </context:component-scan>

    17: @Scope("prototype") 注解可以控制生命周期
    @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.INTERFACES)
    18:
    @Required 注解应用于 bean 属性的 setter 方法。它表明受影响的Bean属性必须在配置时填充
    @Required 
    public void setAge(Integer age)
    { this.age = age; }

    19:
    @Autowired

    @Autowired为Spring提供的注解只按照byType注入。可以注解构造方法,成员变量和set成员方法上面

    每个类只能有一个构造器被标记为@Autowired(required=true)

    @Autowired的必要属性,建议使用@required注解


    可以使用@Autowired注解哪些众所周知的解析依赖性接口,比如BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEventPublisher,and MessageSource

    可以通过添加注解给需要该类型的数组(set,list)的字段或方法,以提供ApplicationContext中的所有特定类型的bean
      public Set<MovieCatalog> movieCatalogs;
      @Autowired
      public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs){
      所有set的泛型中声明的这种bean,也包括这个泛型的子类,都放到了这个集合中去了
      this.movieCatalogs=movieCatalogs;
      }
      可以用于装配key为String的Map
      public Map<String,MovieCatalog> movieCatalogs;
      @Autowired
      public void setMovieCatalogs(Map<String,MovieCatalog> movieCatalogs){
      这个key,即String表示的内容是所有的bean的id,value就是bean的对象
      this.movieCatalogs=movieCatalogs;
      }
      如果希望(放在set,list或mao)数组有序,可以让bean实现org.springframework.core.Ordered接口或使用@Order注解

    基于泛型的自动装配

    @Autowired
    private Store<String> s1;

    @Autowired
    private Store<Integer> s2;

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

    @Bean
    public IntegerStore integerStore() {
    return new IntegerStore();
    }


    public class IntegerStore implements Store<Integer> {

    }
    public interface Store<T> {

    }

    @Autowired是由Spring BeanPostProcessor处理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型应用这些注解,这些类必须通过XML或者Spring的@Bean注解加载

    20:@Qualifier注解

    <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">

    <qualifier value="mysqlDataSource"/>

    </bean>

    <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

    <qualifier value="oracleDataSource"/>

    </bean>

    @Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常

    @Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下:

    @Qualifier(value = "限定标识符")  可以是这样设置<qualifier value="oracleDataSource"/>  也可以是beanid
    可用于限定字段、构造器参数或者方法参数,也可以注解集合类型中的变量

       @Autowired
        @Qualifier("service")
        EmployeeService employeeService;


    public class TestBean {

    private DataSource dataSource;

    @Autowired
    public void initDataSource(@Qualifier("oracleDataSource") DataSource dataSource){
    this.dataSource = dataSource;
    }

    public DataSource getDataSource() {
    return dataSource;
    }
    }

    还可以用另外一种实现方式

    @Autowired
    @Qualifier(value="oracleDataSource")
    public void initDataSource(DataSource dataSource){
    this.dataSource = dataSource;
    }

     xml 中配置如下

    <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">
    <qualifier value="mysqlDataSource"/>
    </bean>

    21:@Autowired @Qualifier  @Resource

    @Autowired可以作用于构造方法,字段,和多个参数的方法中 可以配合@Qualifier缩小范围

    @Resource 是jsr250中的,如果没有指定name值 默认是从属性名和setter方法中取得,可以作用于字段和只有一个参数的set方法中,所以目标是构造器或者多个参数的方法时最好是使用@Qualifier

    因语义差异,集合或Map类型的bean无法通过@Autuwired来注入,因为没有匹配到这样的bean,为这些bean使用@Resource注解,通过唯一名称引用集合或Map的bean

    22:@Resource
    只能注解注解标注set方法和成员变量
    • 注解标注set方法时省略name属性,如setXXX(),则name值默认为xXX,去掉“set”,首字母小写。
    • 注解直接标注变量时省略name属性,则那么name值默认与所标注变量名相同。
     

    Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

    所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

    23:@PostConstruct和@PreDestroy 

    Java EE5 引入了@PostConstruct和@PreDestroy这两个作用于Servlet生命周期的注解,实现Bean初始化之前和销毁之前的自定义操作

    24: 用@Bean标识一个用于配置和初始化一个由SpringIOC容器管理的新对象的方法,也就是说通过@Bean可以生成一个IOC容器的bean实例,类似于XML配置文件的<bean/>。 

    可以在Spring的@Component注解的类,然后在类中使用@Bean注解任何方法(仅仅是可以),然后在方法中去创建对象,进行返回。
    上一点中,通常使用的是@Configuration和@Bean配合使用。

    @Configuration
    public class AppConfig {
    
        @Bean
        public MyService myService() {
            return new MyServiceImpl();
        }
    
    }


    生成对象的名字:默认情况下用@Bean注解的方法名作为对象的名字。但是可以用 name属性定义对象的名字.也可以设置初始化和销毁方法

     
    @Configuration
    public class AppConfig {
    
        @Bean(name = "myFoo",initMethod = "init",destroyMethod = "cleanup") 

    public Foo foo() { return new Foo(); } }
    25: @ImportResource和@Value进行资源文件读取
    通过xml导入资源文件
    <beans> <context:annotation-config/>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
    <bean class="com.acme.AppConfig"/>
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/> </bean>
    </beans>
    也可以通过如下实现

    @Configuration
    @ImportResource("classpath:/com/acme/properties-config.xml")
    public class AppConfig{

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
    return new DriverManagerDataSource(url,username,password);
    }
    }

    <beans xmlns="http://www.springframework.org/schema/beans">
    <context:property-placeholder location="classpath:/config.properties"/>
    </beans>

    
    

    26:@Inject注解

    1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。

    2、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;

    3、@Inject可以作用在变量、setter方法、构造函数上。

    a、将@Inject可以作用在变量、setter方法、构造函数上,和@Autowired一样

    27:@Name 和@Component等同

     @Named和Spring的@Component功能相同。@Named可以有值,如果没有值生成的Bean名称默认和类名相同。

    @Named("demoService_A_impl")
    public class DemoService_A_impl implements DemoService{

    }

    通过name注解缩小范围

    @Inject
    public void setTeacher(@Named("Teacher") People teacher) {
    this.teacher = teacher;
    }

    通过name注解缩小范围

    @Inject
    @Named("demoService_B_impl") //指定注入实现类B
    private DemoService demoService;

    28:Resource

    public class MoocResource implements ApplicationContextAware {

    private ApplicationContext applicationContext;

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

    public void resource() throws IOException {
    Resource resource = applicationContext.getResource("config.txt");
    System.out.println(resource.getFilename());
    System.out.println(resource.contentLength());
    }

    }

     @Primary-在spring中的使用

     在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了

  • 相关阅读:
    Leetcode练习(Python):树类:第117题:填充每个节点的下一个右侧节点指针 II:给定一个二叉树 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。 初始状态下,所有 next 指针都被设置为 NULL。
    高可用OpenStack(Queen版)集群-5.Glance集群
    高可用OpenStack(Queen版)集群-4.keystone集群
    高可用OpenStack(Queen版)集群-3.高可用配置(pacemaker&haproxy)
    高可用OpenStack(Queen版)集群-2.基础服务
    高可用OpenStack(Queen版)集群-1. 集群环境
    GlusterFS分布式存储集群-2. 使用
    GlusterFS分布式存储集群-1. 部署
    高可用Kubernetes集群-15. 部署Kubernetes集群统一日志管理
    高可用Kubernetes集群-14. 部署Kubernetes集群性能监控平台
  • 原文地址:https://www.cnblogs.com/zyy1688/p/9565478.html
Copyright © 2020-2023  润新知