今天来说一下Spring注解
注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好。不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就不会显得那么被动了。
1.@Configuration注解
1.1@Configuration + <context>
该类等价 与XML中配置beans,相当于Ioc容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean,与xml中配置的bean意思一样。
@Configuration注解的类必需使用<context:component-scanbase-package=”XXX”/>扫描.如下:
例:
程序结构图:
(1)首先建立Perons.java,person实体类
package com.zk.Bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
public class Person {
public Person() {
System.out.println("Person初始化");
}
}
(2)其次在建立MainApp.java
package com.zk.Main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.zk.Bean.Person;
public class MainApp {
public static void main(String[]args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(Person.class);
}
}
(3)ApplicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.zk.Bean" />
</beans>
运行结果:
1.2、@Configuration启动容器+@Bean注册Bean,@Bean下管理bean的生命周期
(1)首先建立TestBean.java,实体类
package com.zk.Bean;
import org.springframework.beans.factory.annotation.Value;
public class TestBean {
@Value("zk")
private String name;
private String url;
private String password;
@Override
public String toString() {
return "TestBean [name=" + name + ", url=" + url + ", password="
+ password + "]";
}
public void sayHello(){
System.out.println(name+":sayHello");
}
public void start(){
System.out.println(name+":start");
}
public void cleanup(){
System.out.println(name+":cleanup");
}
}
(2)创建TestConfigure.java
package com.zk.Bean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class TestConfigure {
public TestConfigure(){
System.out.println("TestConfiguration...");
}
@Bean
@Scope("prototype")
TestBean testBean(){
return new TestBean();
}
}
(3)创建ApplicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.zk.Bean" />
</beans>
(4)创建TestMain.java
package com.zk.Bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestMain {
public static void main(String[]args)
{
// @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
ApplicationContext context=new AnnotationConfigApplicationContext(TestConfigure.class);
//获取bean
TestBean tb=(TestBean) context.getBean("testBean");
tb.sayHello();
}
}
运行结果如下:
2.@Value注解
在程序中使用@Value的注解是为了给变量赋值,如上面的注解:
@Value("zk")
private String name;
使用
// @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
ApplicationContext context=new AnnotationConfigApplicationContext(TestConfigure.class);
//获取bean
TestBean tb=(TestBean) context.getBean("testBean");
tb.sayHello();
调用getBean()方法可以获取到name的值。
3. @Controller, @Service, @Repository,@Component
目前4种注解意思是一样,并没有什么区别,区别只是名字不同。使用方法:
(1)创建com.zk.component,创建TestObject.java
package com.zk.component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class TestObject {
@PostConstruct
public void contructbefore(){
System.out.println("初始化之前的操作");
}
@PreDestroy
public void contructAfter(){
System.out.println("初始化之后的操作");
}
}
(2)创建com.zk.controller,并创建UserController.java
package com.zk.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
public void execute(){
System.out.println("UserController execute...");
}
}
(3)创建com.zk.Service,并创建UserService.java
package com.zk.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void add(){
System.out.println("UserService add..");
}
}
(4)创建com.zk.Repository,并创建UserRepository.java和UserRepositoryImpl.java
package com.zk.UserRepository;
public interface UserRepository {
public void save();
}
package com.zk.UserRepository;
import org.springframework.stereotype.Repository;
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository{
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("UserRepository save");
}
}
(5)最后,实现MainAPP实现类:
MainAPP.java
package Main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zk.UserRepository.UserRepository;
import com.zk.component.TestObject;
import com.zk.controller.UserController;
import com.zk.service.UserService;
public class MainAPP {
public static void main(String[]args)
{
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
TestObject to=(TestObject) ac.getBean("testObject");
System.out.println(to.toString());
UserService us=(UserService) ac.getBean("userService");
us.add();
UserRepository ur=(UserRepository)ac.getBean("userRepository");
ur.save();
UserController uc=(UserController)ac.getBean("userController");
uc.execute();
}
}
ApplicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.zk.controller" />
<context:component-scan base-package="com.zk.component" />
<context:component-scan base-package="com.zk.UserRepository" />
<context:component-scan base-package="com.zk.service" />
</beans>
执行Main后结果如下:
4. @PostConstruct 和 @PreDestory
实现初始化和销毁bean之前进行的操作,只能有一个方法可以用此注释进行注释,方法不能有参数,返回值必需是void,方法需要是非静态的。
TestObject.java
package com.zk.component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class TestObject {
@PostConstruct
public void contructbefore(){
System.out.println("初始化之前的操作");
}
@PreDestroy
public void contructAfter(){
System.out.println("初始化之后的操作");
}
}
MainAPP.java
package Main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zk.component.TestObject;
public class MainAPP {
public static void main(String[]args)
{
AbstractApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
TestObject to=(TestObject) ac.getBean("testObject");
System.out.println(to.toString());
((AbstractApplicationContext) ac).close();
}
}
applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.zk.component" />
</beans>
执行结果如下:
@PostConstruct:在构造方法和init方法(如果有的话)之间得到调用,且只会执行一次。
@PreDestory:注解的方法在destory()方法调用后得到执行。
引深一点,Spring 容器中的 Bean 是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下三种:
1.通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
2.通过 <bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;
3.在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用
但他们之前并不等价。即使3个方法都用上了,也有先后顺序.
Constructor > @PostConstruct >InitializingBean > init-method
5. @Autowired
@Autowired是用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源。
UserDao.java
package com.zk.dao;
public interface UserDao {
public void sayHello();
}
UserDaoImpl.java
package com.zk.dao;
import org.springframework.stereotype.Repository;
@Repository("UserDao")
public class UserDaoImpl implements UserDao{
public void sayHello(){
System.out.println("userdao hello");
}
}
UserService.java
package com.zk.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zk.dao.UserDao;
@Service
public class UserService {
@Autowired
private UserDao userdao;
public void sayHello(){
userdao.sayHello();
}
}
Main.App
package Main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zk.service.UserService;
public class MainApp {
public static void main(String[]args)
{
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService object = (UserService) ctx.getBean("userService");
object.sayHello();
}
}
执行MainApp
6. @Primary
(1)首先创建fruit接口,并建立继承fruit接口的两个子类Apple.java,Pear.java,在Pear.java中添加@Primary,将Pear类设为优先。
fruit.java
package com.zk.mybean;
import org.springframework.stereotype.Component;
public interface fruit {
public void sayHello();
}
Apple.java
package com.zk.mybean;
import org.springframework.stereotype.Component;
@Component
public class Apple implements fruit{
public void sayHello(){
System.out.println("Apple Hello");
}
}
Pear.java
package com.zk.mybean;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class Pear implements fruit{
public void sayHello(){
System.out.println("Pear Hello");
}
}
(2)创建fruitService.java
package com.zk.myservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zk.mybean.fruit;
@Service
public class fruitService {
@Autowired
public fruit fruit;
public void getfruit(){
fruit.sayHello();
}
}
(3)最后,实现MainAPP.java和ApplicationContext.xml
package Main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zk.mybean.fruit;
import com.zk.myservice.fruitService;
public class MainAPP {
public static void main(String[]args)
{
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
fruitService fs=(fruitService) ac.getBean(fruitService.class);
fs.getfruit();
}
}
执行结果如下: