I don't think that good developers are good because they're overly smart and well suited for the work. Being smart is definitely a plus as it helps get to the heart of problems faster, but even the blade of the keenest intellect will be rendered blunt by the muffling sheathe of ignorance.
Waxing poetic aside, you can't do a good job if you don't know what you're doing. No matter how good you think you might be, you can be better by research, study, and experimentation. I feel that this sentiment applies not only to programming, but to all matters of life. The driving force behind this reckless abandon in the pursuit of knowledge and research is passion. You might not have a passion for your job, but hopefully you have a passion for programming (assuming your a programmer... insert other career as it will work well enough in substitute). If you don't, consider finding a different career, one you have a drive and desire to succeed in. You'll go farther in an area you have a passion for than one you don't. It's better to be an expert at a "lesser" career than a bad or mediocre at a "higher" career. No one wants a rocket surgen that doesn't really have a passion for rocket surgery.
"But how?" you may ask, thinking that just saying to 'research' without any idea of what goal to pursue isn't very helpful advice at all. Well that might be true, but everyone's passions, interests, and job requirements will differ so saying 'learn about parallel processing' or 'research distributed computing' or 'learn Ruby, it's awesome' isn't very helpful either. But there are a few methods you can use to start your exploration.
The main idea is to explore areas around your current job, but perhaps not directly related. Try learning a different language that you could, theoretically, implement your same work project in if you knew the ins and outs of it. Maybe start a personal project at home that uses that language to discover the differences between it and something else you already use. Sometimes the features of one language can give you ideas how to better use the one you're stuck with. If you've ever used closures in Ruby (or another language that has them), you'll start thinking about your Java or C code quite a bit differently.
Another excellent thing to do is learn a new framework or way of doing things that is not the norm for your day to day job. Let's say you're writing web apps that deal with a lot of relational database transactions and data manipulation. Try learning about non-relational databases such as object databases or NoSQL. There are many open sourced, non-sql dependent databases that you can try out to learn how you can store and retrieve semi-structured data in a non-relational way. Try to figure out the benefits you gain with your current methods, and compare them to the benefits you'd gain if you switched to a different one. You probably won't switch your work project over, most people don't have the authority to do such a thing, but it's still useful because you'll open your eyes to different ways of doing things which will end up translating to useful knowledge in your daily job.
Learn a new language every year. Do personal projects in that language. If it's scripting, maybe make some scripts to help your day to day life out a little. Knowing how to utilize more langages will help you appreciate the differences of them and allow you to be better able to pick the best tool for a given job. It also doesn't hurt when someone at the office starts asking for someone with experience in some new language and you're the one who knows anything about it. Embrace change, and don't get stuck in a rut.
Learn something new every day. Be it a use for a framework, a new language feature, or just something about your own code. Continually learning is critical in the high tech field, as you're knowledge goes out of date way faster than a lot of other professions. Letting yourself get out of date is like letting a knife rust. It won't be very useful to its user for long, and will be replaced if it gets too far worn.
Test your code before you write it. Test Driven Development really works. You'll end up writing way more test code than you ever did before, which is a good thing. You might also notice that you structure your code differently if you write your tests first. The main idea is to allow each piece of code to be tested individually from any other piece of code. If you have a class that you want to test a method of, you should be able to fully test that method without implementing any other class. Any reliance on another classes behavior should be implemented through mock objects. Keep your code decoupled and program based on interfaces. It might not be a bad idea to look into a dependency injection framework, or to get familiar with the finer points of the factory design pattern.
Learning and knowledge is the key to success in our world. I would much rather have someone who's passionate and willing to put in some work to learn how things work and how to do things better than the average day to day code monkey on my team rather than a good code monkey. The second can implement things that I ask for, but the first can invent new implementations and design reusable code that is worth 3x the code monkey.