【spring框架】spring的几个Annotation实现(上)

时间:2022-10-06 01:01:03


spring除了XML的配置,还可以用Annotation注解来实现spring的配置功能,下面来介绍里面一些配置方法

1.Annotation第一步

a)修改xml文件,参考文档<context:annotation-config/>



基于注解(Annotation-based)的配置



在 Spring 2.5中已经可以用注解的方式去驱动 Spring 的依赖注射了。更重要的是,@Autowired注解提供了与第 3.3.5 节 “自动装配(autowire)协作者”一节中描述的同样功能,并且提供了更细致的控制与更好的适应性。Spring 2.5 也支持 JSR-250 中的一些注解,例如@Resource,@PostConstruct,以及@PreDestroy。



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

<context:annotation-config/>

</beans>


(加载了<context:annotation-config/>就相当于隐式注册 post-processors, 包括了 AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,也包括了前面提到的RequiredAnnotationBeanPostProcessor四个bean,用来完成注解的加载)


加了:xmlns:context="http://www.springframework.org/schema/context"


与<context:annotation-config/>


xsd定义了它所控制的xml都能写什么,就是我们当前文件的命名空间(装着我能写的名字)




2.Autowired


a)默认按类型by type



例子:


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

<context:annotation-config/>

<bean class="cn.edu.hpu.dao.Impl.UserDaoImpl">
<property name="daoId" value="1"></property>
</bean>

<bean class="cn.edu.hpu.service.UserService">
</bean>

</beans>


注意,此时userService的bean里面并没有加id=u的bean。我们用注解来进行AutoWired


在UserService的getUserDao方法上面加注解@Autowired(默认byType)


package cn.edu.hpu.service;

import org.springframework.beans.factory.annotation.Autowired;

import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.dao.Impl.UserDaoImpl;
import cn.edu.hpu.model.User;


public class UserService {


private UserDao userDao;

public void init(){
System.out.println("init");
}

public UserDao getUserDao() {
return userDao;
}
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}


public void add(User u){
this.userDao.save(u);
}

public void destroy(){
System.out.println("destroy");
}

}



测试:


package cn.edu.hpu.service;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.model.User;


public class UserServiceTest {

@Test
public void testAdd() throws Exception{
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");

UserService userService=(UserService)ctx.getBean("userService");
System.out.println(userService.getUserDao());
ctx.destroy();
}
}



UserDaoImpl.java:改写了toString方法,返回daoId


package cn.edu.hpu.dao.Impl;

import java.util.List;
import java.util.Map;
import java.util.Set;


import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.model.User;


public class UserDaoImpl implements UserDao{

private int daoId;

public int getDaoId() {
return daoId;
}

public void setDaoId(int daoId) {
this.daoId = daoId;
}

public void save(User u) {
System.out.println("add success!!");
}

@Override
public String toString() {

return "daoid="+daoId;
}

}



测试结果:


daoid=1


也就是用Annotation也可以实现Autowired




b)如果想用byName,使用@Qulifier




如果有好几个Type一样的,就应该用byName了:


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

<context:annotation-config/>

<bean class="cn.edu.hpu.dao.Impl.UserDaoImpl">
<property name="daoId" value="1"></property>
</bean>
<bean class="cn.edu.hpu.dao.Impl.UserDaoImpl">
<property name="daoId" value="2"></property>
</bean>

<bean class="cn.edu.hpu.service.UserService">
</bean>

</beans>


在UserService的getUserDao方法的参数前加@Qualifier("XX"),其中


"XX"是相应bean的id


UserService.java:


package cn.edu.hpu.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.dao.Impl.UserDaoImpl;
import cn.edu.hpu.model.User;


public class UserService {


private UserDao userDao;

public void init(){
System.out.println("init");
}

public UserDao getUserDao() {
return userDao;
}
@Autowired
public void setUserDao(@Qualifier("u2")UserDao userDao) {
this.userDao = userDao;
}


public void add(User u){
this.userDao.save(u);
}

public void destroy(){
System.out.println("destroy");
}

}


测试:


package cn.edu.hpu.service;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.model.User;


public class UserServiceTest {

@Test
public void testAdd() throws Exception{
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");

UserService userService=(UserService)ctx.getBean("userService");
System.out.println(userService.getUserDao());
ctx.destroy();
}
}

结果:


daoid=2


说明注解@Qualifier("u2")起到了作用




c)写在private filed(第三种输入形式)(不建议,破坏封装)


@Autowired(required=false)就是可以去自动获取,如果没有也可以不要(可有可无)




d)如果写在set上,@qualifier需要写在参数上




补充:


前面在XML中提到的ini-method和的destroy-method用注解实现就是在相应方法上加:


@PostConstruct与@PreDestroy



@Scope("XXX")里面指定是用什么样的生命范围(singleton、prototype)