spring之IOC总结

注入方式

  1. 通过IOC容器创建对象,并为属性赋值★
//日期类型的注入
 <bean id="dateFormat" class="java.text.SimpleDateFormat">
        <constructor-arg value="yyyy-MM-dd"></constructor-arg>
    </bean>
    <bean id="date" factory-bean="dateFormat" factory-method="parse">
        <constructor-arg value="2015-12-31"></constructor-arg>
    </bean>
<bean id="person01" class="com.kuang.Person">
        <property name="name" value="狂神"></property>
        <property name="age" value="25"></property>
        <property name="id" value="123"></property>
    </bean>
  1. 根据bean的类型从IOC容器中获取bean的实例★
 ApplicationContext ioc = new ClassPathXmlApplicationContext("application.xml");
//        Person person = (Person) ioc.getBean("person01");
//        Person person = ioc.getBean("person01",Person.class);
  1. 通过构造器为bean的属性赋值(index,type属性介绍)
<bean id="person03" class="com.kuang.Person">
        <constructor-arg name="name" value="小明"></constructor-arg>
        <constructor-arg name="age" value="25"></constructor-arg>
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="bir" ref="date"></constructor-arg>
    </bean>
  1. ·通过p名称空间为bean赋值
导入标签
 xmlns:p="http://www.springframework.org/schema/p"
 注入属性
    <bean id="person04" class="com.kuang.Person" p:age="28" p:id="456" p:name="haha">
    </bean>

5.级联属性的注入

<property name="car" ref="car01"/>
<property name="car.price" value="900000"/>

6.通过继承实现bean的配置信息重用

<bean id="person05" class="com.kuang.Person"  parent="person04">
        <property name="bir" ref="date"></property>
    </bean>

7.通过工厂注入(静态工厂、实例工厂)

  <!--静态工厂-->
    <bean id="factoryPerson" class="com.kuang.PersonFactory" factory-method="getPerson">
    </bean>
  <!--实例工厂-->
    <bean id="dateFormat" class="java.text.SimpleDateFormat">
        <constructor-arg value="yyyy-MM-dd"></constructor-arg>
    </bean>
    <bean id="date" factory-bean="dateFormat" factory-method="parse">
        <constructor-arg value="2015-12-31"></constructor-arg>
    </bean>

8.创建带有生命周期方法的bean

实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Nullable
    /*
    初始化之前调用的方法
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[" + beanName +"]bean方法将要调用初始化方法了" );`在这里插入代码片`
        return bean;
    }
    /*
    初始化之后调用的方法
     */
    @Nullable
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[" + beanName +"]bean方法将要调用处理方法了");
        return bean;
    }
}
//注册对象
<bean id="beanPostProcessor" class="com.kuang.MyBeanPostProcessor"></bean>

9.通过注解加bean加入IOC容器中
@Service
@Controller
@Repository
@Component
使用注解加入到容器中的组件,组件的id,默认为组件的类名首字母小写,单例
可以通过组件如@Service(“bookDao”) @Scope(value=“prototype”)

<context:component-scan base-package="com.kuang"/>

排除扫描

 <context:component-scan base-package="com.kuang">
        <!--扫描的时候可以排除一些不要的组件
         type="assignable",指定排除某个具体的类,按照类排除
         type="annotation" 指定要排除的规则,按照注解进行排除,标注了指定注解的组件不要
         type="aspectj"
         type="regex"
        expression="": 注解的全类名
        -->
        <context:exclude-filter  type="regex" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    </context:component-scan>

指定只扫描

<context:component-scan base-package="com.kuang" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"></context:include-filter>
</context:component-scan>

@Autowired原理(requireds属性可以更改)
1、先按照类型去容器中找到对应的组件:找到一个就赋值,没找到就抛异常,找到多个则按照变量名作为id继续装配,匹配则装配,若没有匹配则可以用@Qualifier(“bookService”)指定id。也可以加在方法上

依赖泛型注入

public abstract class BaseDao<T> {
    public abstract void save();
}
@Repository
public class BookDao extends BaseDao<Book> {
    @Override
    public void save() {
        System.out.println("保存图书");
    }
}
@Repository
public class UserDao extends BaseDao<Person> {
    @Override
    public void save() {
        System.out.println("保存用户");
    }
}
public class BaseService<T> {
    @Autowired
    BaseDao<T> baseDao;
    public void save() {
        baseDao.save();
    }
}
@Service
public class BookService extends BaseService<Book>{

}
@Service
public class UserService extends BaseService<Person>{

}

@Resource:扩展性更强,因为是java标准

  1. 如何为对象list中注入属性
    spring的单元测试
@ContextConfiguration(locations = "classpath:application.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestDemo {
    @Autowired
    @Qualifier("person01")
    Person person;
public class Book {
    private List<String> books;
    private Map<String,Object> maps;
    private Properties properties;
}
<list>
      <!-- <value>张三</value String类型>
          <value>李四</value>-->
          <ref bean="person01"></ref>
          <bean class="com.kuang.Person" p:age="28" p:id="456" p:name="haha"/>
</list>
  1. 如何为map中注入属性
  <property name="maps">
            <map>
                <entry key="key01" value="张三"></entry>
                <entry key="key02" value-ref="person01"></entry>
                <entry key="key03">
                    <bean class="com.kuang.Person" p:age="28" p:id="456" p:name="haha"/>
                </entry>
            </map>
        </property>

3.为Properties注入属性

<property name="properties">
            <!--properties中所有的k=v都是String类型的-->
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>

提取公共的list map

<util:map id="myMap">
        <entry key="key01" value="张三"></entry>
        <entry key="key02" value-ref="person01"></entry>
    </util:map>

注意:
xml中基本类型的会自动转化
对象的创建按照配置的循序创建bean(可以通过dependence进行更改)
按照类型获取组件,可以获取到这个类型下所有的实现类子类(有多个就报错)
引用外部文件

 <context:property-placeholder location="classpath:dbconfig.properties"/>

自动装配
autowire=“byName” 以属性名作为id去容器中找到这个组件,给他赋值
autowire="byType"以属性的类型作为查找依据去容器中找到这个组件
autowire="constructor"按照构造器进行赋值;1.想按照有参类型进行装配,没有就直接为组件赋值为null 2.如果按照类型找到多个,参数的名作为id继续装配;找到就装配,找不到就null
SPEL注入格式#{}调用

<property name="id" value="#{T(java.util.UUID).randomUUID().toString()}"></property>

xml属性注入需要提供get/setter方法 自动@Autowired不需要提供
复杂类型的注入要在标签外进行

<constructor-arg name="bir"><null/></constructor-arg>

ref为严格的引用外部bean 内部bean的
bean的作用域

prototype:多实例
获取的时候才开始创建
singleton:默认为单实例
在容器启动完成之前已经创建好对象,保存在容器中了
任何获取都是获取之前创建好的那个对象
request:web环境下
session

内部bean
<property name="bir">
            <bean factory-bean="dateFormat" factory-method="parse">
                <constructor-arg value="2015-12-31"></constructor-arg>
            </bean>
 </property>
 //外部bean
  <constructor-arg name="bir" ref="date"></constructor-arg>

对象对应bean标签

配置注意事项
1)、src,源码包开始的路径,称为类路径的开始即/bin
源码包里面的东西都会合并到类路径里面
web:/WEB-INF/classes/
new ClassPathXMLApplicationContext(“ioc.xml”);IOC配置文件在类路径下;
new FileSystemXmlApplicationContext("F:/ioc.xml); IOC容器的配置文件在磁盘路径下;

Date类型注入

测试Bean:

public class DateBean {
private Date birthday;

public Date getBirthday() {
    return birthday;
}

public void setBirthday(Date birthday) {
    this.birthday = birthday;
}

}

方式1:利用SimpleDateFormat的构造方法注入
 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" 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="dateFormat" class="java.text.SimpleDateFormat">
    <constructor-arg value="yyyy-MM-dd" />
    </bean>
    <bean id="datebean" class="com.springDemo1.Date类型注入.DateBean">
        <property name="birthday">
            <bean factory-bean="dateFormat" factory-method="parse">
                <constructor-arg value="2015-12-31" />
            </bean>
        </property>
    </bean>
</beans>
方式2:纯配置,先自定义CustomDateEditor,再转换类型
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" 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="dateEditor"
        class="org.springframework.beans.propertyeditors.CustomDateEditor">
        <constructor-arg>
            <bean class="java.text.SimpleDateFormat">
                <constructor-arg value="yyyy-MM-dd"></constructor-arg>
            </bean>
        </constructor-arg>
        <constructor-arg value="true" />
    </bean>
    <!-- 使 Spring转换为java.util.Date -->
    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="java.util.Date">
                    <ref bean="dateEditor" />
                </entry>
            </map>
        </property>
    </bean>
</beans>
方式3:先用一个类重写PropertyEditorSupport的setAsText方法,再在配置文件中,配置转换类型就可以了,跟上面方法类似
public class MyDatePropertyEditor extends PropertyEditorSupport {
    private String format;
 
    public String getFormat() {
        return format;
    }
 
    public void setFormat(String format) {
        this.format = format;
    }
 
    // text为需要转换的值,当为bean注入的类型与编辑器转换的类型匹配时就会交给setAsText方法处理
    public void setAsText(String text) throws IllegalArgumentException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            this.setValue(sdf.parse(text));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" 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">
 
    <!--方式3:创建一个类 重写PropertyEditorSupport的setAsText方法 -->
    <!-- 自定义日期编辑器 -->
    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">  <!--需要编辑的属性类型,是一个map -->
            <map>
                <entry key="java.util.Date">
                    <bean class="com.springDemo1.Date类型注入.MyDatePropertyEditor">
                        <property name="format" value="yyyy-MM-dd" />  <!--注入需要转换的格式 -->
                    </bean>
                </entry>
            </map>
        </property>
    </bean>
</beans>
测试:
public class DateTest {
    @Test
    public void testName() throws Exception {
        
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        
        DateBean bean = (DateBean) context.getBean("datebean");
        System.out.println(bean.getBirthday());
    }
}

支持当前事务

  1. PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  2. PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  3. PAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。
    不支持当前事务的情况:
  4. PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  5. PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  6. PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于

spring对象作用域
Spring 3中为Bean定义了5中作用域,分别为singleton(单例)、prototype(原型)、request、session和global session,5种作用域说明如下:
springAOP
JDK动态代理
利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,
在调用具体方法前调用InvokeHandler来处理。
CGLiB动态代理
利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
JDK和CGLib的性能对比
使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
在JDK1.6、JDK1.7、JDK1.8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLib代理效率,只有当进行大量调用的时候,JDK1.6和JDK1.7比CGLib代理效率低一点,但是到JDK1.8的时候,JDK代理效率高于CGLib代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值