Spring注解

今天来说一下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,@Qualifier

@Autowired是用在JavaBean中的注解,默认通过byType形式查找Bean,如果发现多个Bean,则使用byName形式查找Bean,用来给指定的字段或方法注入所需的外部资源。 

可以手动使用@Qualifier注解给需要通过byName形式查找的Bean进行赋值,例如

@Autowired
@Qualifier(“pean”)
public Fruit fruit; 

 

 

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();
	}
}

 执行结果如下:

 

posted @ 2019-08-02 20:40  leagueandlegends  阅读(193)  评论(0编辑  收藏  举报