spring详细学习笔记2

1 xml文件导入其他xml文件配置
如果我们在spring框架中配置了多个xml文件,我们可以在读取配置文件的时候把这些xml文件一下全都读取,也可以只读一个总的xml文件,在这个总的xml文件中把其他的xml全都都导入进来。
例如:
student.xml文件:

  <bean name="student" class="com.briup.bean.Student">
          <property name="id">
               <value>25</value>
          </property>
     </bean>
 teacher.xml文件:
 <bean name="teacher" class="com.briup.bean.Teacher">
     <property name="student" ref="student"></property>
 </bean>

 import.xml文件:
 <import resource="teacher.xml"/>
 <import resource="student.xml"/>

测试类:
main:

    String[] path = {"com/briup/ioc/imp/import.xml"};
     ApplicationContext container =
               new ClassPathXmlApplicationContext(path);
 Teacher t = (Teacher) container.getBean("teacher");
 System.out.println(t.getStudent());

2 spring容器创建bean对象的方式
1)xml文件中有bean的配置,而且这个bean所对应的java类中存在一个无参构造器,那么这个时候Spring容器就可以使用反射调用无参构造器来创建实例了(常规的方式)

2)通过工厂类获得实例(工厂类实现了接口FactoryBean<?>)
      注意spring中的PropertyPlaceholderConfigurer类的使用,在htmlsingle中直接搜索类名即可
      例如:
 //工厂类实现指定接口并且实现接口中的三个抽象方法:
  public class ConnectionFactory implements FactoryBean<Connection>{
          private String driver;
          private String url;
          private String username;
          private String password;

          @Override
          public Connection getObject() throws Exception {
               Class.forName(driver);
               Connection conn =
                    DriverManager.getConnection(url,username,password);
               return conn;
          }

          @Override
          public boolean isSingleton() {
               return false;
          }
         
          @Override
          public Class<Connection> getObjectType() {
               return Connection.class;
          }
          set/get
          ....
    }
xml文件:

 <!--
     下面配置的这个类,可以自动的帮我们去读取指定的properties文件的内容,文件中用key-value的形式存放数据,读完之后我们就可以用${key}这种形式去拿文件中的value值了
     classpath指的是从src下面找.
-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     <property name="location">
          <value>classpath:oracle.properties</value>
     </property>
</bean>

简写:
<context:property-placeholder location=“classpath:oracle.properties” />

     因为这个类是一个工厂类,所以我们用名字conn在容器中拿对象的时候,
     拿到并不是这个工厂类对象,而是这个工厂类对象调用完工厂方法后所返回的对象.
 <bean name="conn" class="com.briup.ioc.factory.ConnectionFactory">
        <property name="driver">
          <value>${driver}</value>
        </property>
        <property name="url">
         <value>${url}</value>
        </property>
        <property name="username">
         <value>${user}</value>
        </property>
        <property name="password">
         <value>${password}</value>
        </property>
    </bean>

测试类

  String path = "com/briup/ioc/factory/factory.xml";
                    ApplicationContext container =
                                 new ClassPathXmlApplicationContext(path);
                    Connection conn=(Connection) container.getBean("conn");
                    System.out.println(conn);
                    conn.close();

3 自定义事件
在spring中我们可以自定义事件,并且可以使用ApplicationContext类型对象(就是spring容器container)来发布这个事件
事件发布之后,所有的ApplicaitonListener(监听器)实例都会被触发并调用指定方法onApplicationEvent()来处理.
事件源继承ApplicationEvent —监听器引用ApplicationListener
例如:
自定义事件类RainEvent:

 public class RainEvent extends ApplicationEvent {
          public RainEvent(Object source) {
               super(source);
          }
     }
  监听器类RainListener1
     public class RainListener1 implements ApplicationListener<RainEvent>{

          @Override
          public void onApplicationEvent(RainEvent event) {
               System.out.println("唐僧大喊:" + event.getSource() + "赶快收衣服喽!");
          }

     }

     监听器类RainListener2
     public class RainListener2 implements ApplicationListener<RainEvent>{

          public void onApplicationEvent(RainEvent event) {
               System.out.println("我们:" + event.getSource() + "太好了不用上课了!");
          }
     }
 xml文件:
 <!-- 只需要把这俩个监听器类交给spring容器管理就可以了 -->
 <bean class="com.briup.ioc.event.RainListener1"></bean>
 <bean class="com.briup.ioc.event.RainListener2"></bean>

 main:
 String path = "com/briup/ioc/event/event.xml";
 ApplicationContext container =
      new ClassPathXmlApplicationContext(path);
 container.publishEvent(new RainEvent("下雨了!"));

4 ioc中的annotation配置

 @Autowired
 1) @Autowired使用后需要在xml文件加入以下配置才能生效: <context:annotation-config/>
 2) @Autowired注解可以写在成员变量、setter方法、构造器函数上面
 3) @Autowired默认按照byType匹配的方式进行注入,如果没有一个bean的类型是匹配的则会抛异常,如果有多个bean的类型都匹配成功了,那么再按byName方式进行选择
 4) @Autowired如果最终匹配不成功(注意一定是一个都没有找到的情况)则会抛出异常,但是如果设置为 @Autowired(required=false),则最终匹配不成功没有不会抛出异常。
 5) @Autowired可以结合@Qualifier("beanName")来使用,则可以达到byName的效果

注意 @Autowired
@Qualifier(“beanName”)
==@Resource(“beanName”)

  @Resource
 1) @Resource使用后需要在xml文件加入以下配置才能生效:<context:annotation-config/>
 2) @Resource的作用和@Autowired差不多,只不过 @Resource是默认先用byName,如果找不到合适的就再用byType来注入
 3) @Resource有俩个属性,name和type,使用name属性则表示要byName匹配,使用type属性则表示要byType匹配
   
 @PostConstruct和@PreDestroy
 1) 标注了@PostConstruct注解的方法将在类实例化后调用
 2) 标注了@PreDestroy注解的方法将在类销毁之前调用


 @Component
 1) @Component注解可以直接定义bean,而无需在xml定义。但是若两种定义同时存在,xml中的定义会覆盖类中注解的Bean定义
 2) @Component注解直接写在类上面即可
 3) @Component有一个可选的参数,用于指定bean的名称
      @Component("boss")
      public class Boss{}
 4) @Component如果不指定参数,则bean的名称为当前类的类名小写
      //和上面例子的相关相同
      @Component
      public class Boss{}
 5) @Component使用之后需要在xml文件配置一个标签
      <context:component-scan/>
 6) <context:component-scan base-package="com.briup.ioc.annotation" />
      表示spring检查指定包下的java类,看它们是否使用了 @Component注解
 7) @Component定义的bean默认情况下都是单例模式的,如果要让这个bean变为非单例,可以再结合这个@Scope注解来达到目标@Scope("prototype")


 @Component是Spring中所有bean组件的通用形式, @Repository @Service @Controller 则是 @Component的细化,用来表示更具体的用例,分别对应了持久化层、服务层和表现层。但是至少到现在为止这个四种注解的实质区别很小(甚至几乎没有),都是把当前类注册为spring容器中的一个bean

 注意:
 1.component-scan标签默认情况下自动扫描指定路径下的包(含所有子包)
 2.component-scan标签将带有@Component @Repository @Service @Controller注解的类自动注册到spring容器中
 3.component-scan标签对标记了@Required @Autowired @PostConstruct @PreDestroy @Resource @WebServiceRef @EJB   @PersistenceContext @PersistenceUnit等注解的类进行对应的操作,使注解生效
 4.component-scan标签包含了annotation-config标签的作用
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页