Spring 依赖注入,注解,AOP及Junit

初学spring,还是感觉东西有点杂的,难度不大就是有点碎,还是记录一下吧。

1. 依赖注入

  • 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/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

这是先引入的命名空间, 文件命名为applicationContext.xml。
如果我要在spring容器注册一个bean,则可以在applicationContext里加入以下代码

<bean id="user" class="com.kjy.domain.User" scope="prototype">
	<!--普通属性-->
	<property name="username" value="kang"/>
    <property name="age" value="23"/>
    <!--list 集合属性-->
    <property name="habits">
        <list>
            <value>eat</value>
            <value>sleep</value>
            <value>code</value>
        </list>
    </property>
    <!--map 集合属性-->
    <property name="map">
        <map>
            <entry key="1" value="A"/>
            <entry key="2" value="B"/>
            <entry key="3" value="C"/>
        </map>
    </property>
</bean>

此时相应类(com.kjy.domain.User)要有相应的setter方法(setUsername,setAge,setHabits等等),其中list和map里面的元素也可以是复杂数据类型、一些自定义的类的实例等等,标签变为相应的-ref就行。这里scope的取值是多例的意思,相应的"singleton"是单例的意思,不写就默认单例。

<bean id="person" class="com.kjy.demo.Person" scope="prototype">
        <constructor-arg name="username" value="sun"/>
        <constructor-arg name="age" value="32"/>
</bean>

这是构造方法依赖注入。和setter方法相似,constructor-arg代替property,需要注意的是,这里name属性的取值是构造方法的形参的意思。
类似的,我们可以写出数据源的实例化代码:

<context:property-placeholder location="classpath:druid.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="url" value="${url}"/>
        <property name="maxActive" value="${maxActive}"/>
        <property name="maxWait" value="${maxWait}"/>
        <property name="initialSize" value="${initialSize}"/>
</bean>
  • 注解方式(推荐)
    比较先进的做法(也是比较快速方便的写法)就是使用注解,首先在applicationContext文件里加入:
<!--扫描指定包下所有类并筛选出特定注解的类注册为bean添加到容器中-->
<context:component-scan base-package="com.kjy"/>

然后以UserService为例:

//注册(Service代表这是服务层的类,其他可选注解有Reposity,Controller,Component等,代表不同语义)
@Service("userService")
//单例(默认)
@Scope("singleton")
public class UserServiceImpl implements UserService {
	//下面注解的意思是从spring容器中匹配符合筛选条件的bean注入成员变量
    /*
    @Autowired	//代表按类型注入
    @Qualifier("userDao")	//代表按名称注入
     */

    @Resource	//相当于上面两个注解的作用
    private UserDao userDao;

	@Value("value")	//普通数据类型
	private String string;
}

@Repository("userDao")
public class UserDaoImpl implements UserDao {
}

发现对于非自定义的类,这种方式似乎失效。这里可以扩展一下,对于非自定义的类,我们也可以采用注解的方式,以DruidDataSource为例:

@Configuration	//表明这是配置类
@ComponentScan("com.kjy")	//指定扫描包
@Import({DataSourceConfig.class})	//导入其他部分的配置类
public class SpringConfig {
}

@PropertySource("classpath:druid.properties")	//指定配置文件
public class DataSourceConfig {
    @Value("${username}")
    private String username;

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

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

    @Value("${driverClassName}")
    private String driverClassName;

    @Value("${maxActive}")
    private String maxActive;

    @Value("${maxWait}")
    private String maxWait;

    @Value("${initialSize}")
    private String initialSize;

    @Bean("dataSource")
    public DataSource getDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setMaxActive(Integer.valueOf(maxActive));
        dataSource.setMaxWait(Integer.valueOf(maxWait));
        dataSource.setInitialSize(Integer.valueOf(initialSize));
        return dataSource;
    }
}

2. AOP
AOP就是面向切面编程,是面向对象编程的衍生,其核心是通过动态代理的方式增强对象的某些方法。
同样,也可以分为xml方式和注解方式。

  • xml

这是一个简单的例子:

<bean id="target" class="com.kjy.aop.Target"/>

<bean id="aspect" class="com.kjy.aop.MyAspect"/>

        <aop:config>
            <aop:aspect ref="aspect">
            	<!--
            	<aop:before method="before" pointcut="execution(public void com.kjy.aop.Target.method())">
            	-->
                <aop:pointcut id="myPointcut" expression="execution(public void com.kjy.aop.Target.method())"/>
                <aop:before method="before" pointcut-ref="myPointcut"/>
            </aop:aspect>
        </aop:config>

这里,Aspect为切面类,Target.method()方法是切点。切面类中的方法是为切点服务的(切点+切面类的方法=增强方法),实现动态代理。
除了<aop:before/> 标签以外,还有<aop:after-returnning><aop:after>等等标签,分别代表不同的添加位置。

  • 注解(推荐)
    注解可以简化配置xml文件的繁琐过程,仍以上文为例:
@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method(){
        System.out.println("original method...");
    }
}

@Component("myAspect")
@Aspect	//表示这是一个切面类
public class MyAspect {
    @AfterReturning("execution(public void com.kjy.aop.Target.method())")
    public void afterReturn(){
        System.out.println("this is afterReturn operation...");
    }

    @Around("execution(* com.kjy.aop.Target.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("前置增强...");
        Object obj = pjp.proceed();
        System.out.println("后置增强...");
        return obj;
    }
}

这里要注意需要在applicationContext.xml文件加入这样一行:

<aop:aspectj-autoproxy/>

3. Junit
Junit的基本用法:

import org.junit.Test;
public class AopTest {

    @Test
    public void test(){
    	ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    	TargetInterface target = app.getBean("target");
    	app.method();
    }
}

发现每次写测试方法的时候都要先获取具体对象才能测试其方法,感觉有点麻烦。
此时可以采用下面这种写法:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {

    @Resource(name = "target")
    private TargetInterface target;

    @Test
    public void test(){
        target.method();
    }
}

暂时写到这里吧,其实好多内容写的太粗略没有展开,还是因为我太懒了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值