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();
}
本文深入探讨了Spring框架中几种关键的组件注解,包括@Configuration、@Component、@Service、@Controller、@Repository等,解释了它们的用途、特性和如何在实际项目中应用。
341

被折叠的 条评论
为什么被折叠?



