Spring的注解开发(一)

基于注解的Spring应用

Spring的注解开发-注解版本和@Component简介

Spring除了xml配置文件进行配置之外,还可以使用注解方式进行配置,注解方式慢慢成为xml配置的替代方案。

Spring提供的注解有三个版本:

  • 2.0时代,Spring开始出现注解
  • 2.5时代,Spring的Bean配置可以使用注解完成
  • 3.0时代,Spring其他配置也可以使用注解完成,进入全注解时代

基于Bean注解,主要是使用注解的方式替代原有xml的bean标签及其标签属性的配置

<bean id="" name="" class="" scope="" lazy-init="" init-method="" destroy-method="" abstract="" autowire="" facatory-bean="" factory-method=""></bean>

使用@Component注解替代标签

xml配置注解描述
bean id=“” class=“”@Component被该注解标识的类,会在指定扫描范围内被Spring加载并实例化

Spring的注解开发-@Component使用

//<bean id="userDao" name="com.lucifa.dao.impl.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao {

}

applicationContext.xml中
使用注解对需要被Spring实例化的Bean进行标注,需要告诉Spring去哪找这些Bean,要配置组件扫描路径

<beans xmlns="..." ...>

	<!--注解组件扫描:扫描指定的基本包及其子包下的类,识别使用@Conponent注解>
	<context:component-scan base-package="com.luxifa"/>
</beans>

主程序:

public class ApplicationContextTest {
	
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Object userDao = applicationContext.getBean("userDao");
		System.out.println(userDao);
	}
}

控制台打印:

com.luxifa.dao.impl.UserDaoImpl@799d4f69

可以通过@Component注解的value属性指定当前Bean实例的beanName,也可以省略不写,不写的情况下为当前类名首字母小写

//获取方式:applicationContext.getBean("userDao");
@Component("userDao")
public class UserDaoImpl implements UserDao {
}

//获取方式:applicationContext.getBean("userDaoImpl");
@Component
public class UserDaoImpl implements UserDao {
}

Spring的注解开发-作用范围等注解使用

Spring通过注解方式去配置之前标签中的那些属性,例如:@Scope

<bean id="" name="" class="" scope="" lazy-init="" init-method="" destroy-method="" abstract="" autowire="" facatory-bean="" factory-method=""></bean>
xml配置注解描述
bean scope=“”@Scope在类上或使用了@Bean标注的方法上,标注Bean的作用范围,取值为singleton或prototype
bean lazy-init=“”@Lazy在类上或使用了@Bean标注的方法上,标注Bean是否延迟加载,取值为true和false
bean init-method=“”@PostConstruct在方法上使用,标注Bean的实例化后执行的方法
bean destroy-method=“”@PreDestroy在方法上使用,标注Bean的销毁前执行方法
@Component("userDao")
@Scope("singleton")
@Lazy(false)
public class UserDaoImple implements UserDao {
	public UserDaoImpl() {
		System.out.println("userDao创建");
	}

	@PostConstruct
	public void init() {
		Syste.out.println("userDao的初始化方法");
	}

	@PreDestroy
	public void destroy() {
		System.out.println("userDao的销毁方法");
	}
}

Spring的注解开发-@component的三个衍生注解

由于JavaEE开发是分层的,为了每层Bean标识的注解语义化更加明确,@Component又衍生出如下三个注解:

@Component衍生注解描述
@Repository在Dao层类上使用
@Service在Service层类上使用
@Controller在web层类上使用
@Repository("userDao")
public class UserDaoImpl implements UserDao {}

@Service("userService")
public class UserServiceImpl implements UserService {}

@Controller("userService")
public class UserController {}

Spring的注解开发-依赖注入相关注解

Bean依赖注入的注解,主要是使用注解的方式替代xml的标签完成属性的注入操作

<bean id="" class="">
	<property name="" value=""/>
	<property name="" ref=""/>
</bean>

Spring主要提供如下注解,用于在Bean内部进行属性注入的:

属性注入注解描述
@Value使用在字段或方法上,用于注入普通数据
@Autowired使用在字段或方法上,用于根据类型(byType)注入引用数据
@Qualifier使用在字段或方法上,结合@Autowired,根据名称注入
@Resource使用在字段或方法上,根据类型名称进行注入

@Value
1.

@Scope("singleton")
@Lazy(false)
public class UserDaoImple implements UserDao {

	/方式1 @Value("luxifa")
	private String username;
	
    //方式2
	@Value("luxifa")
	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public void show() {
		System.out.println(username);
	}
}

applicationContext.xml中

<beans xmlns="..." ...>

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

	<!--注解组件扫描:扫描指定的基本包及其子包下的类,识别使用@Conponent注解>
	<context:component-scan base-package="com.luxifa"/>
</beans>

jdbc.propertie中

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=...
jdbc.url=...
jdbc.password=root...
@Scope("singleton")
@Lazy(false)
public class UserDaoImple implements UserDao {

	@Value("${jdbc.driver}")
	private String username;

	@Override
	public void show() {
		System.out.println(username);
	}
}

@Autowired
如果组件只有一个有参构造器,这个有参构造器的 @Autowired 可以省略,参数位置的组件还是可以自动从容器中获取

@Bean+方法参数:参数从容器中获取,默认不写 @Autowired 效果是一样的,都能自动从容器中获取

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    
    //方式1
	@Autowired //根据类型进行注入
	private UserDao userDao;

	//方式2
	//@Autowired 这个地方注解不能省略
	public void setSuserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void show() {
		System.out.println(userDao);
	}
}

@Qualifier

UserDaoImpl.java

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

UserDaoImpl2.java

@Repository("userDao2")
public class UserDaoImpl2 implements UserDao{
   
	@Override
	public void show() {
		
	}
}
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    
	@Autowired //根据类型进行注入,如果同一类型的Bean有多个,尝试根据名字进行儿媳匹配,匹配不成则报错
	@Qualifier("userDao2") //在此,结合@Autowired一起使用,作用是根据名称注入相应的Bean
	private UserDao userDao;

	@Override
	public void show() {
		System.out.println(userDao);
	}
}

@Resource
@Resource单独使用时,相当于@Autowired注解
@Resource(name=“”),相当于 @Autowired+@Qualifier

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    
	//@Autowired //根据类型进行注入,如果同一类型的Bean有多个,尝试根据名字进行儿媳匹配,匹配不成则报错
	//@Qualifier("userDao2") //在此,结合@Autowired一起使用,作用是根据名称注入相应的Bean
	@Resource(name="userDao2") //不指定名称参数时,根据类型注入,指定名称就根据名称注入
	private UserDao userDao;

	@Override
	public void show() {
		System.out.println(userDao);
	}
}

Spring的注解开发-非自定义Bean的配置

非自定义Bean不能像自定义Bean一样使用@Component进行管理,非自定义Bean要通过工厂的方式进行实例化,使用@Bean标注方法即可,@Bean的属性为beanName,如不指定为当前工厂方法名称

@Component
public class OtherBean {

	//将方法返回值bean实例以@Bean注解指定的名称存储到Spring容器中
	@Bean("dataSource")
	public DataSource dataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/mytatis");
		dataSource.setUsername("root");
		dataSource.setPassword("root");
		return dataSource;
	}
}

此外,工厂方法所在类必须要被Spring管理。

如果@Bean工厂方法需要参数的话,则有如下几种注入方式:

  • 使用@Autowired根据类型自动进行Bean的匹配,@Autowired可以省略;
  • 使用@Qualifier根据名称进行Bean的匹配
  • 使用@Value根据名称进行普通数据类型匹配
@Bean
@Autowired //根据类型匹配参数
public Object objectDemo01(UserDao userDao) {
	System.out.println(userDao);
	return new Object();
}

@Bean
public Object objectDemo02(@Qualifier("userDao2") UserDao userDao,@Value("${jdbc.username}") String username) {
	System.out.println(userDao);
	System.out.println(username);
	return new Object();
}

@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
	
	@Override
	public void show () {
	}
}

Spring的注解开发-Spring配置类的开发

@Component等注解替代了bean标签,但是像import、context:componentScan等非bean标签该如何使用注解替代?

<!--加载properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--组件扫描-->
<context:component-scan base-package="com.luxifa"/>
<!--引入其他xml文件-->
<import resource="classpath:beans.xml"/>

定义一个配置类替代原有的xml配置文件,标签以外的标签,一般都是在配置上使用注解完成的


@Configuration注解标识的类为配置类,替代原有xml配置文件,该注解第一个作用是标识该类是一个配置类,四二个作用是具备@Component作用

@Configuration
public class ApplicationConTextConfig {}

@ComponentScan组件扫描配置,替代原有xml中的<context:component-scan base-package=“”/>

@Configuration
@ComponentScan({"com.luxifa.service","com.luxifa.dao"})
public class ApplicationContextConfig {}

base-package的配置方式:

  • 指定一个或多个包名:扫描指定包及其子包下使用注解的类
  • 不配置包名:扫描当前@ComponentScan注解配置类所在包及其子包下的类

@PropertySource注解用于记载外部properties资源配置,替代原有xml中的<context:property-placeholder location=“”/>配置

@Configuration
@ComponentScam
@PropertySource({"classpath:jdbc.properties","classpath:xxx.properties"})
public class ApplicationContextCOnfig {}

@Import用于加载其他配置类,替代原有xml中的import resource=“classpath:beans.xml” 配置

@Configuration
@ComponentScan
@PropertySource("classpath:jdbc.properties")
@Import(OtherConfig.class)
public class ApplicationContextCOnfig {}
public class OtherBean {

	//将方法返回值bean实例以@Bean注解指定的名称存储到Spring容器中
	@Bean("dataSource")
	public DataSource dataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/mytatis");
		dataSource.setUsername("root");
		dataSource.setPassword("root");
		return dataSource;
	}
}

Spring的注解开发-Spring配置其他注解

扩展:@Primary注解用于标注相同类型的Bean优先被使用权,@Primary是Spring3.0引入的,与@Component和@Bean一起使用,标注该Bean的优先级更高,则在通过类型获取Bean或通过@Autowired根据类型进行注入时,会选用优先级更高的

@Service("userService")
public class UserServiceImpl implements UserService {
	@Autowired
	private UserDao userDao;

	@Override
	public void show() {
		System.out.println(userDao);
	}
}
@Repository("userDao")
public class UserDaoImpl implements UserDao {
	
	@Override
	public void show() {
	}
	
}
@Repository("userDao2")
@Primary
public class UserDaoImpl2 implments UserDao {
	
	@Override
	public void show() {
	}
	
}

主程序:

public class ApplicationContextTest {
	
	public static void main(String[] args) {
		//注解方式去加载Spring的核心配置类
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
		UserService userService = applicationContext.getBean(UserService.class);
		userService.show();
	}
}

控制台输出:

com.luxifa.dao.impl.UserDaoImpl2@5fb230b4

@Primary也这样使用

@Bean
public UserDao userDao01() {return new UserDaoImpl();}

@Bean
@Primary
public UserDao userDao02() {return new UserDaoImpl2();}

扩展:@Profile注解的作用同于xml中的profile属性,用于进行环境切换使用

<beans profile="test">

注解@Profile标注在类或方法上,标注当前产生的Bean从属于哪个环境,只有激活了当前环境,被标注的Bean才能被注册到Spring容器里。不指定环境的Bean,任何环境下都能注册到Spring容器里

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

}

主程序:

public class ApplicationContextTest {
	
	public static void main(String[] args) {
		
		System.setProperty("spring.profiles.active","test");
				//注解方式去加载Spring的核心配置类
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
		Object userDao= applicationContext.getBean("userDao");
		System.out.println(userDao);
	}
}

控制台打印:

com.luxifa.dao.impl.UserDaoImpl@33afa13b

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值