Spring IOC 基于注解的使用

本文深入探讨了Spring框架中几种关键的组件注解,包括@Configuration、@Component、@Service、@Controller、@Repository等,解释了它们的用途、特性和如何在实际项目中应用。
package com.zghw.spring.demo.demo.annontaion;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.zghw.spring.demo.demo.annontaion.app.AppConfig;
import com.zghw.spring.demo.demo.annontaion.app.ConfigA;
import com.zghw.spring.demo.demo.annontaion.app.MyProfile;
import com.zghw.spring.demo.demo.annontaion.app.component.Bar;

/**
 * @Configuration 是被元数据 @Component 注解过的,so 它们都是会被扫描器@ComponentScan扫描,因为扫描器会扫描到
 *                对应的包中,@ComponentScan("com.zghw.spring.demo.demo.annontaion"),
 *                对扫描到的类调用,然后刷新容器,运行它们的 @Bean methods,作为BeanDefintion注册到容器中.
 * @author zghw
 *
 */
public class Application {
	public static void main(String args[]) {
		/**
		 * 使用spring驱动配置类,创建一个AnnotationConfigApplicationContext,配置@Configurable下的类作为输入
		 * ,@ComponentScan 作为扫描标记器. 构建AnnotationConfigApplicationContext不仅支持 @Configuration
		 * 还支持所有 @Component 组件。
		 * 
		 * @Configuration 会首先注册自己的BeanDefinition,然后注册该注解类下所有的 @Bean
		 *                方法返回的类的BeanDefinition
		 * @Component 中只有使用了元注解 @autowired 或 @inject 才会注册BeanDefinition
		 *            个人认为:不建议使用@Component组件来定义,使用 @Configuration
		 *            让它在@Component包的上层,加载@Configuration下的类,
		 *            扫描它对应的当前包中的类和当前包包含的所有类。
		 */
		// ApplicationContext ctx = new
		// AnnotationConfigApplicationContext(AppConfig.class);
		// ctx=new AnnotationConfigApplicationContext(new
		// Class<?>[]{MyBean.class,MyServiceImpl.class});
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		//设置环境变量
		ctx.getEnvironment().setActiveProfiles("prod");
		ctx.register(AppConfig.class);
		ctx.refresh();

		/*f(ctx.getBean("mybean"));
		f(ctx.getBean("myControllerBean"));
		f(ctx.getBean("bussiness"));
		f(ctx.getBean("foo"));*/
		ConfigA config = (ConfigA)ctx.getBean("configA");
		MyProfile myProfile = (MyProfile)ctx.getBean(MyProfile.class);
		f(config.myUrl());
		f(myProfile.getMyLocationSQL());
		Bar bar=(Bar)ctx.getBean("myBar");
		bar.test();
	}

	static void f(Object o) {
		System.out.println(o);
	}
}

这个是Configuration的注解

package com.zghw.spring.demo.demo.annontaion;

import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Role;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

@Lazy(false)
@Primary
@DependsOn("facde")
@Role(0)
@Description("set annotation")
@Scope(scopeName="sc",proxyMode=ScopedProxyMode.DEFAULT)
@Component
@ComponentScan
@Import(MyAnnotation.class)
@ImportResource(locations="application.xml",reader=XmlBeanDefinitionReader.class)
/**
 * 多个路径,分成字段,使用环境资源解析value路径,转换为resource,添加到环境中。
 * @author zghw
 *
 */
@PropertySource(name="aa",value="a.properties,b.properties",ignoreResourceNotFound=true)
public class MyAnnotation {

}

package com.zghw.spring.demo.demo.annontaion.app;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;

import com.zghw.spring.demo.demo.annontaion.app.component.Bar;
import com.zghw.spring.demo.demo.annontaion.app.component.Foo;
import com.zghw.spring.demo.demo.annontaion.app.component.MyBean;
import com.zghw.spring.demo.demo.annontaion.app.controller.MyController;
import com.zghw.spring.demo.demo.annontaion.app.repository.MyRepository;
import com.zghw.spring.demo.demo.annontaion.app.repository.MyRepositoryImpl;
import com.zghw.spring.demo.demo.annontaion.app.service.MyService;
import com.zghw.spring.demo.demo.annontaion.app.service.MyServiceImpl;

/**
 *@Configuration 是一个类级别的注解,对象对应的BeanDefition的一个源产地.
 *定义的beans是通过被 @Bean 注解过的方法返回的bean.
 *调用 @Bean 下的方法会自动解析依赖关系.
 * 
 * 全配置 @Configuration vs 简化配置 @Beans
 * 如果 @Bean 不是配置在 @Configuration 中,那么这个bean就是简化配置,
 * 比如:这个 @Bean 是配置在 @Component 中或者普通类下,就是简化配置。
 * @Bean 配置在 @Configuration 是全配置模式
 * 简化配置时,一个bean调用另一个bean是方法的调用,AOP的时候会出现代理该类。
 * 不太懂!说是简化配置时,这个bean时工厂方法产生的bean,是CGlib动态代理,
 * AOP拦截不到。
 * 反正spring 就是建议你写在 @Bean 在 @Configuration 注解的类下使用就是了。
 * 
 * 
 * @ComponentScan 组件扫描器,默认扫描 被 @Configuration 定义类对应的包下面的所有类
 * 
 * @Import(ConfigA.class)导入应一个 @Configuration 标记的类,用来合并bean
 * @author zghw
 *
 */
@Configuration
@ComponentScan("com.zghw.spring.demo.demo.annontaion")
@Import({ConfigA.class,FactoryBeanConfig.class})
public class AppConfig {
	/**
	 * @Bean 方法级别的注解 
	 * 应用在方法上得到方法返回的实例,并初始化一个新的BeanDefintion有IOC容器管理。
	 * 就像xml中的<bean>元素一样.
	 * 方法的名字就是id,方法返回对象的类型就是class
	 * myControllerBean  --> com.zghw.spring.demo.demo.annontaion.app.controller.MyController
	 * 依赖:方法参数就是依赖的对象 com.zghw.spring.demo.demo.annontaion.app.service.MyService
	 * 你可以 @Bean 注解一个在任何 @Component 组件中的方法上,
	 * 但通常的它一般用于注解在 @Configuration 中的方法上返回对象。
	 * 使用 @Configuration 注解的类,代表了这个类的主要目的就是配置Bean定义。就像
	 * 一个XML文档一样,另外它允许 @Bean 可以通过调用其他 @Bean 方法建立依赖关系。
	 * @return
	 */
	/**
	 * 初始化方法和销毁方法
	 * scope设置
	 * 描述符
	 * parent不用配置 直接引用方法就是了
	 * 抽象的就不定义扫描它就行了
	 * @return
	 */
	@Bean(name="myB",initMethod="init",destroyMethod="cleanup")
	@Scope(scopeName=ConfigurableBeanFactory.SCOPE_PROTOTYPE,proxyMode=ScopedProxyMode.TARGET_CLASS)
	@Description("Provides a basic example of a bean")
	public MyBean myBean(){
		return new MyBean();
	}
	@Bean
	public MyController myControllerBean(MyService facde){
		facde.getMessage();
		return new MyController();
	}
	/**
	 * 别名
	 * @return
	 */
	@Bean(name={"facde","bussiness"})
	public MyService myServiceBean(){
		return new MyServiceImpl();
	}
	/**
	 * Primary如果接口实现有多个,优先注入该bean
	 * @return
	 */
	@Bean
	@Primary 
	public MyService myServiceBean2(){
		return new MyServiceImpl();
	}
	@Bean
	public MyRepository myRepositoryBean(){
		return new MyRepositoryImpl();
	}
	
	@Bean
	public Bar myBar(){
		Bar bar=new Bar();
		bar.setName("sdfsddfs");
		return bar;
	}
	
	/**
	 * 内部引用bean只在@Configuration下使用 ,不要在 @Component 所有组件使用
	 * @return
	 */
	@Bean
	public Foo foo(){
		return new Foo(bar());
	}
	@Bean
	public Bar bar(){
		return new Bar();
	}
	
}

package com.zghw.spring.demo.demo.annontaion.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import com.zghw.spring.demo.demo.User;
import com.zghw.spring.demo.demo.annontaion.app.controller.MyController;
import com.zghw.spring.demo.demo.annontaion.app.service.MyService;

/** 
 * @ImportResource 导入资源xml资源 一般是bean定义
 *  @PropertySource导入属性properties资源 使用Environment得到变量
 * @author zghw
 *
 */
@Configuration
@ImportResource("classpath:application-test-annotation.xml")
@PropertySource("my-prod.properties")
public class ConfigA {
	@Autowired
	private Environment env;
	/**
	 * 在xml配置属性占位符,设置参数
	 */
	@Value("${jdbc.username}")
	private String username;
	@Value("${jdbc.password}")
	private String password;
	@Value("${jdbc.driver}")
	private String driver;
	@Value("${jdbc.url}")
	private String url;
	
	public String myUrl(){
		return username+" "+password+" "+driver+" url";
	}
	
	/**
	 * @Profile 设置配置的环境
	 * @return
	 */
	@Bean
	@Profile("prod")
	public MyProfile prodProfile(){
		return new MyProfile(env.getProperty("alias"));
	}
	@Bean
	@Profile("test")
	public MyProfile testProfile(){
		return new MyProfile("test");
	}
	@Bean
	@Profile("default")
	public MyProfile defaultProfile(){
		return new MyProfile("default");
	}
	/**
	 * 依赖bean自动的注入
	 * 当 @Bean 配置在 @Configuration 下,
	 * 该 @Bean 的方法参数就是依赖的对象,方法参数名字和其他 @Bean 注解过的方法名称相同匹配,
	 * 则spring会自动的帮你维护依赖关系,创建或查找依赖的对象,你直接调用这个方法就可以了。
	 * @param myControllerBean
	 * @param bussiness
	 * @return
	 */
	@Bean
	public User myUser(MyController myControllerBean,MyService bussiness){
		System.out.println(myControllerBean.excute(bussiness));
		return new User();
	}
}

package com.zghw.spring.demo.demo.annontaion.app;

public class MyProfile {
	private String myLocationSQL;

	public MyProfile(){}
	
	public MyProfile(String myLocationSQL) {
		super();
		this.myLocationSQL = myLocationSQL;
	}

	public String getMyLocationSQL() {
		return myLocationSQL;
	}

	public void setMyLocationSQL(String myLocationSQL) {
		this.myLocationSQL = myLocationSQL;
	}
	
}

package com.zghw.spring.demo.demo.annontaion.app.component;

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

import com.zghw.spring.demo.demo.Computer;
import com.zghw.spring.demo.demo.annontaion.app.service.MyService;

public class Bar {
	@Value("1215")
	private String name;
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 属性的注入
	 *  @Autowired 用来表示属性将有sprnig自动注入的注入
	 *  @Qualifier 用来规定注入的规则。使用beanName来限定当前的注入
	 */
	@Autowired
	@Qualifier("myServiceBean2")
	private MyService facde;
	@Autowired
	private Bar b;
	
	private Computer computer;
	
	public Bar(){
		System.out.println("是否在会自动的构造");
	}
	
	public Computer getComputer() {
		return computer;
	}

	
	public void setComputer(Computer computer) {
		this.computer = computer;
	}
	
	public void test(){
		
		System.out.println(facde.getMessage()+"=  "+b.getName());
	}
	
}

package com.zghw.spring.demo.demo.annontaion.app.component;

public class Foo {
	public Foo(){}
	public Foo(Bar bar){
		
	}
}

package com.zghw.spring.demo.demo.annontaion.app.component;

import org.springframework.stereotype.Component;

/**
 * 使用@Component被注解的类代表是一个“组件”,
 * 当使用自动扫描classpath下的类时,会自动的把被@Component注解过的类加入到候选类中。
 * 它是一个通用组件的概念。而 @Repository, @Service, and @Controller 是它的更具体的用例子。
 * @author zghw
 *
 */
@Component("mybean")
public class MyBean {
	
	/**
	 * 初始化方法
	 */
	public void init(){
		System.out.println("初始化MyBean");
	}
	/**
	 * 销毁方法
	 */
	public void cleanup(){
		System.out.println("销毁MyBean");
	}
}

package com.zghw.spring.demo.demo.annontaion.app.controller;

import org.springframework.stereotype.Controller;

import com.zghw.spring.demo.demo.annontaion.app.service.MyService;
/**
 * 使用@Controller被注解的类经常被代表是一个“控制器”(例如web控制器),
 * 当使用自动扫描classpath下的类时,会自动的把被@Controller注解过的类加入到候选类中。
 * 它是作为一个专业化的 @Component组件
 * @author zghw
 *
 */
@Controller
public class MyController {
	public String excute(MyService ms){
		return ms.getMessage();
	}
}

package com.zghw.spring.demo.demo.annontaion.app.repository;

import org.springframework.stereotype.Repository;
/**
 * 使用@Repository被注解的类经常被代表是一个“数据访问层”(例如DAO),
 * 当使用自动扫描classpath下的类时,会自动的把被@Repository注解过的类加入到候选类中。
 * 它是作为一个专业化的 @Component组件
 * @author zghw
 *
 */
@Repository
public class MyRepositoryImpl implements MyRepository{

}

package com.zghw.spring.demo.demo.annontaion.app.repository;

public interface MyRepository{

}

package com.zghw.spring.demo.demo.annontaion.app.service;

import org.springframework.stereotype.Service;
/**
 * 使用@@Service被注解的类经常被代表是一个“服务”(例如业务 服务  Business Service Facade),
 * 当使用自动扫描classpath下的类时,会自动的把被@Service注解过的类加入到候选类中。
 * 它是作为一个专业化的 @Component组件
 * @author zghw
 */
@Service
public class MyServiceImpl implements MyService {

	public String getMessage() {
		String message="message= I'm service Impl";
		return message;
	}

}

package com.zghw.spring.demo.demo.annontaion.app.service;

public interface MyService {

	String getMessage();
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值