Spring基础

Spring基础

IOC部分

【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="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

【注入类型】

如上例,通过配置bean,完成类型注入。

注入的方法有三种:

  1. setter注入

    <bean id="exampleBean" class="examples.ExampleBean">
        <!-- setter injection using the nested ref element -->
        <property name="beanOne">
            <ref bean="anotherExampleBean"/>
        </property>
        <!-- setter injection using the neater ref attribute -->
        <property name="beanTwo" ref="yetAnotherBean"/>
        <property name="integerProperty" value="1"/>
    </bean>
    
  2. 构造方法注入

    <bean id="exampleBean" class="examples.ExampleBean">
    	<!-- constructor injection using the nested ref element -->
        <constructor-arg>
            <ref bean="anotherExampleBean"/>
        </constructor-arg>
    
        <!-- constructor injection using the neater ref attribute -->
        <constructor-arg ref="yetAnotherBean"/>
    
        <constructor-arg type="int" value="1"/>
    </bean>
    

    type是通过类型自动匹配,index是通过索引匹配。

  3. 接口注入(由于破坏了类的封装,所以不提倡使用)

id和name 存在些许不同,比如name 可以使用特殊字符。但是基本作用相同。

【简单属性注入】

简单属性是指类似int,String这样的属性。

第一种方法:采用name+value直接将值注入。

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- results in a setDriverClassName(String) call -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="masterkaoli"/>
</bean>

第二种方法:通过p命名空间配置,更加简洁。但是据说IDEA等部分IDE才可以用。

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="com.mysql.jdbc.Driver"
        p:url="jdbc:mysql://localhost:3306/mydb"
        p:username="root"
        p:password="masterkaoli"/>

【集合注入】

可以注入的集合包括List, Set, Map, 和 Properties。分别对应了标签<list/>, <set/>, <map/>, and <props/> ,集合标签都应该是在依赖注入的时候使用。

<props>
	<prop key="administrator">administrator@example.org</prop>
	<prop key="support">support@example.org</prop>
	<prop key="development">development@example.org</prop>
</props>

<list>
	value>a list element followed by a reference</value>
	<ref bean="myDataSource" />
</list>

<map>
	<entry key="an entry" value="just some string"/>
	<entry key ="a ref" value-ref="myDataSource"/>
</map>

<set>
	<value>just some string</value>
	<ref bean="myDataSource" />
</set>

映射键或值的值或设置值也可以是以下任何元素: bean | ref | idref | list | set | map | props | value | null

空注入的标签为<null/>

【不明显依赖】

如果两个bean之间的初始化顺序存在依赖关系,但是两个bean之间没有从属关系。那么就不可以设置ref来保证两个bean的初始化顺序,可以使用depends-on。设置一个或多个bean的名称来保证当前bean一定在这些bean之后完成初始化。

<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
    <property name="manager" ref="manager" />
</bean>

【自动装配】

让bean自动装配的方法是在<bean />中设置autoware属性,属性的取值如下:

ModeExplanation
no(默认)无自动装配。 必须通过ref元素定义Bean引用。 不建议对较大的部署更改默认设置,因为明确指定协作者可以提供更好的控制和清晰度。 在某种程度上,它记录了系统的结构。
byName按属性名称自动装配。 Spring查找与需要自动装配的属性同名的bean。 例如,如果bean定义按名称设置为autowire,并且它包含master属性(即,它具有setMaster(…)方法),则Spring会查找名为master的bean定义,并使用它来设置 属性。
byType如果容器中只存在一个属性类型的bean,则允许自动装配属性。 如果存在多个,则抛出致命异常,这表示您不能对该bean使用byType自动装配。 如果没有匹配的bean,则没有任何反应; 该物业未设定。
constructor类似于byType,但适用于构造函数参数。 如果容器中没有构造函数参数类型的一个bean,则会引发致命错误。

byType和constructor的区别就在于,如果少了一个对应类型的bean,byType而言只是少装配了一个,对constructor来说将会引发错误。

还可以通过设置在<beans></beans>中设置default-autoware 来完成所有的bean的自动装配选项。

【Bean scopes】

ScopeDescription
singleton默认的选择,也就是单例。
prototype原型。每次通过工厂获取的都是一个新的实例。
request将单个bean定义范围限定为单个HTTP请求的生命周期; 也就是说,每个HTTP请求都有自己的bean实例,它是在单个bean定义的后面创建的。 仅在Web感知Spring ApplicationContext的上下文中有效。
session将单个bean定义范围限定为HTTP会话的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。
globalSession将单个bean定义范围限定为全局HTTP会话的生命周期。 通常仅在Portlet上下文中使用时有效。 仅在Web感知Spring ApplicationContext的上下文中有效。
application将单个bean定义范围限定为ServletContext的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。
websocket将单个bean定义范围限定为WebSocket的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。

常用的仅仅是前两种。

【bean的生命周期】

  1. lazy-init

    设置lazy-init="true" 后,所有的bean不会马上在容器中实例化,而是在使用的时候实例化。

  2. init-method 和destroy-method

    通过设置这两个属性,容器对bean初始化的时候调用该init-method指定的方法,容器关闭的时候将会执行destroy-method指定的方法。

【Annotation】

通过注解配置IOC容器注入类型,依赖注入等功能比配置XML实现要简单许多。

首先要在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"
    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">	<!-- * -->

    <context:annotation-config/>
    <context:component-scan base-package="kolo.spring" />
    <!-- * -->

</beans>

注释了*的地方是新加入的。

加入之后就可以在源码中使用Annotation,完成刚刚在XML中才能完成的任务了。

  1. @Autowired

    注释在需要自动装配的方法,构造方法,字段上。将会自动的在IOC容器中通过byType的方式自动的装配,完成依赖注入。

    如果是在字段上注释,那就是接口注入。

  2. @Qualifier

    配置在字段前,方法的参数前,将会让自动装配通过byName的方式完成。

    <bean class="example.SimpleMovieCatalog">
        <qualifier value="main"/>
        <!-- inject any dependencies required by this bean -->
    </bean>
    
    public void prepare(@Qualifier("main")MovieCatalog movieCatalog,
                CustomerPreferenceDao customerPreferenceDao) {
            this.movieCatalog = movieCatalog;
            this.customerPreferenceDao = customerPreferenceDao;
        }
    
  3. @Required

    受该注释的影响的bean属性必须填充,否则将会产生错误。这样是为了将错误提前到编译期间。

  4. __@Resource __

    通过name属性指定bean名称,来注入属性。

    public class SimpleMovieLister {
    
        private MovieFinder movieFinder;
    
        @Resource(name="myMovieFinder")
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
    }
    
  5. @PostConstruct and @PreDestroy

    通过注释在方法前面,效果等同于init-method 和destroy-method

  6. @Component,@Service, @Controller,@Component

    这三个注释在目前没有太大区别,同样都是标记产生bean,注入到容器中。

    使用这三个标签完成类型注入,一定要设置XML,使spring扫描所有的源码。

    设置base-package来扫描不同的package。

    <context:component-scan base-package="org.example"/>
    

AOP部分

Aspect Oriental Program 面向切面编程


【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"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        "> 
    <context:annotation-config/>
    <context:component-scan base-package="kolo.spring" />
    <aop:aspectj-autoproxy />

@Aspect

  该注释用在类声明前,表明被标注的类可能包含pointcut,advice和instrodution。只有被IOC容器管理的类才能使用@Aspect。

@Pointcut

  形如:

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}

声明一个切口,切口名为方法名。切入方法定义在execution中。

@before、@AfterReturning、@AfterThrowing、@Around

  前几个的意义很明显,@Around使用方法如下:

@Around("com.xyz.myapp.SystemArchitecture.businessService()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        Object retVal = pjp.proceed();
        // stop stopwatch
        return retVal;
    }

【XML方式配置】

  前面的配置是在源码中注释实现,还可以在XML配置文件中设置。

声明aspect
<aop:config>
    <aop:aspect id="myAspect" ref="aBean">
        ...
    </aop:aspect>
</aop:config>
pointcut

expression属性配置切面方法名,id是切面引用名。如果pointcut配置在<aop:aspect></aop:aspect>内,那么pointcut的作用域就属于该aspect内。

<aop:pointcut id="businessService"
        expression="execution(* com.xyz.myapp.service.*.*(..))"/>
before、after-returning、after-throwing、around

  pointcut-ref属性为所用pointcut的id,method为切入点方法名。
  使用returns属性指定应将返回值传递到切面方法的参数的名称,如果使用,那么必须存在一个名为doAccessCheck并且存在retVal参数。

  使用throwing属性指定应将异常传递到的参数的名称。

<aop:before pointcut-ref="businessService" method="monitor"/>

<aop:after-returning
        pointcut-ref="dataAccessOperation"
        returning="retVal"
        method="doAccessCheck"/>
        
<aop:after-throwing
        pointcut-ref="dataAccessOperation"
        throwing="dataAccessEx"
        method="doRecoveryActions"/>
<aop:around
        pointcut-ref="businessService"
        method="doBasicProfiling"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值